It is legal to call a variable by a name that begins with a dot (like .identifier
). However, within()
function does not preserve them. Did I miss something? Or is it a bug?
A <- data.frame(.has.a.dot=1:10,has.no.dot=letters[1:10])
within(A, new.variable<-rnorm(10,.has.a.dot))
gives :
has.no.dot new.variable
1 a 1.300361
2 b 3.014026
3 c 2.354260
4 d 4.261637
5 e 5.159326
6 f 7.178712
7 g 6.438039
8 h 8.253819
9 i 9.463351
10 j 8.828403
Using rm() command: When you want to clear a single variable from the R environment you can use the “rm()” command followed by the variable you want to remove. variable: that variable name you want to remove.
You can shift-click to select a range of variables, you can hold shift and press the down key to select one or more variables, and so on. And then you can press Paste and the command with extracted variable names is pasted into your script editor.
This seems to be because of standard in the as.list
method for class environment
. The standard argument is all.names = FALSE
. From ?as.list
:
all.names a logical indicating whether to copy all values or (default) only those whose names do not begin with a dot.
You can change the within.data.frame
method to the following:
within.data.frame <- function (data, expr, ...)
{
parent <- parent.frame()
e <- evalq(environment(), data, parent)
eval(substitute(expr), e)
# l <- as.list(e) # removed this line
l <- as.list(e, all.names=TRUE) # added this line
l <- l[!sapply(l, is.null)]
nD <- length(del <- setdiff(names(data), (nl <- names(l))))
data[nl] <- l
if (nD)
data[del] <- if (nD == 1)
NULL
else vector("list", nD)
data
}
Then you get your expected behavior:
within(A, new <- .has.a.dot)
## .has.a.dot has.no.dot new
## 1 1 a 1
## 2 2 b 2
## 3 3 c 3
## 4 4 d 4
## 5 5 e 5
## 6 6 f 6
## 7 7 g 7
## 8 8 h 8
## 9 9 i 9
## 10 10 j 10
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With