R自我参考

在RI发现自己做了很多这样的事情:

adataframe[adataframe$col==something]<-adataframe[adataframe$col==something)]+1

这种方式是漫长而乏味的。 有没有办法给我
引用我正在尝试改变的对象

 adataframe[adataframe$col==something]<-$self+1 

试试package data.table和它:=运算符。 这是非常快,非常短。

 DT[col1==something, col2:=col3+1] 

第一部分col1==something是子集。 你可以在这里放置任何东西,并使用列名,就好像它们是variables一样; 即不需要使用$ 。 然后第二部分col2:=col3+1将该RHS分配给该子集中的LHS,其中列名可以被分配到,就好像它们是variables一样。 :=是按引用分配的。 没有任何对象的副本被采用,所以比<-=withintransform更快。

另外,即将在v1.8.1中实现, j的语法的一个最终目标是允许:=j就像它将它和by组合起来一样,看问题: 我应该何时在data.table中使用:=运算符 。

UDPDATE:2012年7月确实发布了( :=按组)。

你应该更加关注Gabor Grothendeick(而不仅仅是在这个例子中)。Matt Asher的博客中引用的inc函数完成了你所问的所有内容:

(而且明显的扩展也是如此。)

 add <- function(x, inc=1) { eval.parent(substitute(x <- x + inc)) } # Testing the `inc` function behavior 

编辑:在第一个评论缺乏批准之后,我暂时感到烦恼之后,我接受了添加更多function参数的挑战。 提供一个dataframe的一部分参数,它仍然会增加值的范围一。 到目前为止,只在中缀运算符上进行了非常简单的testing,但是我没有理由认为它不适用于只接受两个参数的函数:

 transfn <- function(x, func="+", inc=1) { eval.parent(substitute(x <- do.call(func, list(x , inc)))) } 

(有罪承认:这从某种意义上来说,从传统的R值的angular度来看是“错误的”)。早期对inc函数的testing如下:

 > df <- data.frame(a1 =1:10, a2=21:30, b=1:2) > inc <- function(x) { + eval.parent(substitute(x <- x + 1)) + } > inc(df$a1) # works on whole columns > df a1 a2 b 1 2 21 1 2 3 22 2 3 4 23 1 4 5 24 2 5 6 25 1 6 7 26 2 7 8 27 1 8 9 28 2 9 10 29 1 10 11 30 2 > inc(df$a1[df$a1>5]) # testing on a restricted range of one column > df a1 a2 b 1 2 21 1 2 3 22 2 3 4 23 1 4 5 24 2 5 7 25 1 6 8 26 2 7 9 27 1 8 10 28 2 9 11 29 1 10 12 30 2 > inc(df[ df$a1>5, ]) #testing on a range of rows for all columns being transformed > df a1 a2 b 1 2 21 1 2 3 22 2 3 4 23 1 4 5 24 2 5 8 26 2 6 9 27 3 7 10 28 2 8 11 29 3 9 12 30 2 10 13 31 3 # and even in selected rows and grepped names of columns meeting a criterion > inc(df[ df$a1 <= 3, grep("a", names(df)) ]) > df a1 a2 b 1 3 22 1 2 4 23 2 3 4 23 1 4 5 24 2 5 8 26 2 6 9 27 3 7 10 28 2 8 11 29 3 9 12 30 2 10 13 31 3 

这是你可以做的。 让我们说你有一个数据框

 df = data.frame(x = 1:10, y = rnorm(10)) 

而且你想把所有的y加1。你可以通过使用transform轻松完成

 df = transform(df, y = y + 1) 

我会偏向(可能是子集在行上)

 ridx <- adataframe$col==something adataframe[ridx,] <- adataframe[ridx,] + 1 

不依赖任何花哨的/脆弱的parsing,对于正在执行的操作是合理的expression,而不是太冗长。 也倾向于将线条划分成很好的人类可分解单位,并且使用标准习语有一些吸引力–R的词汇和特质已经足够我的口味。