Two Dots, ".." in R

Two dots, .. in R

..4 would be a reserved word in R's parser. Under ?Reserved you will find

... and ..1, ..2 etc, which are used to refer to arguments passed down from a calling function.

Example

#  Function will return nth element from ... ( n MUST be a named argument)
f <- function( ... , n = NULL )
return( eval( parse( text = paste0( ".." , n ) ) ) )

# Return third element of ...
f( n = 3 , 1:3 , 3:1 , 10:15 )
#[1] 10 11 12 13 14 15

# Try to return element that is out of bounds
f( n = 4 , 1:3 , 3:1 , 10:15 )
#Error in eval(expr, envir, enclos) :
# the ... list does not contain 4 elements

Now that you know what it is, how do you use it? Courtesy of John Chambers;

"The name ..1 refers to the first matching argument, ..2 to the second, etc. You should probably avoid this obscure convention, which can usually be done by writing a function with some ordinary argument names, and calling it with "...""

Software for Data Analysis: Programming with R, John M. Chambers, Springer-Verlag, New York, 2008.

Excerpt from page 457.

double dots in a ggplot

Unlike many other languages, in R, the dot is perfectly valid in identifiers. In this case, ..count.. is an identifier. However, there is special code in ggplot2 to detect this pattern, and to strip the dots. It feels unlikely that real code would use identifiers formatted like that, and so this is a neat way to distinguish between defined and calculated aesthetics.

The relevant code is at the end of layer.r:

# Determine if aesthetic is calculated
is_calculated_aes <- function(aesthetics) {
match <- "\\.\\.([a-zA-z._]+)\\.\\."
stats <- rep(FALSE, length(aesthetics))
grepl(match, sapply(aesthetics, deparse))
}

# Strip dots from expressions
strip_dots <- function(aesthetics) {
match <- "\\.\\.([a-zA-z._]+)\\.\\."
strings <- lapply(aesthetics, deparse)
strings <- lapply(strings, gsub, pattern = match, replacement = "\\1")
lapply(strings, function(x) parse(text = x)[[1]])
}

It is used further up above in the map_statistic function. If a calculated aesthetic is present, another data frame (one that contains e.g. the count column) is used for the plot.

The single dot . is just another identifier, defined in the plyr package. As you can see, it is a function.

Why does .. work to pass column names in a character vector variable?

This was a new, experimental feature added in data.table v1.10.2. It is explained in the NEW FEATURES section of the data.table news for changes in v1.10.2.

It reads (quoted directly):

When j is a symbol prefixed with .. it will be looked up in calling scope and its value taken to be column names or numbers.

myCols = c("colA","colB")
DT[, myCols, with=FALSE]
DT[, ..myCols] # same

When you see the .. prefix think one-level-up like the directory .. in all operating systems meaning the parent directory. In future the .. prefix could be made to work on all symbols apearing anywhere inside DT[...]. It is intended to be a convenient way to protect your code from accidentally picking up a column name. Similar to how x. and i. prefixes (analogous to SQL table aliases) can already be used to disambiguate the same column name present in both x and i. A symbol prefix rather than a ..() function will be easier for us to optimize internally and more convenient if you have many variables in calling scope that you wish to use in your expressions safely. This feature was first raised in 2012 and long wished for, #633. It is experimental.

Note: This answer by Arun led me to this information.

Replace two dots in a string with gsub

If you are going to use fixed = TRUE, use the (non-interpreted) character .:

> gsub("..", ".", test, fixed = TRUE)

Otherwise, within regular expressions (fixed = FALSE), . has a special meaning (any character) so you'll want to prefix it with a backslash to mean "the dot character":

> gsub("\\.\\.", ".", test)
> gsub("\\.{2}", ".", test)

Split columns considering only the first dot in R using separate

A tidyverse approach would be to first clean the data then separate.

 df %>% 
mutate(col1 = gsub("\\s.*(?=word)", "", col1, perl=TRUE)) %>%
tidyr::separate(col1, into = c("Number", "Words"), sep="\\.")

Result:

# A tibble: 8 x 2
Number Words
<chr> <chr>
1 1 word
2 2 word
3 3 word
4 4 word
5 5 word
6 6 word
7 7 word
8 8 word

error with double dot `..`in R data.table

Based on the error, the 'BTplan' may still be a data.frame. Converting to data.table with setDT or as.data.table should fix it as the .. and the syntax is specific for a data.table object

library(data.table)
names(as.data.table(BTplan)[, ..chrs])

Using a reproducible example

chrs <- sapply(iris, is.numeric)
names(as.data.table(iris)[, ..chrs])
#[1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width"

Renaming doesn't work for column names starting with two dots

..1 is a reserved word in R. See help("reserved") and help("..1"). Try quoting it:

df %>% rename(b = "..1")

giving:

# A tibble: 3 x 2
a b
<int> <int>
1 1 4
2 2 5
3 3 6


Related Topics



Leave a reply



Submit