R自我参考

Los*_*Lin 37 r dataframe self-reference

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

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

这种方式有点冗长乏味.有没有办法让我
引用我想要改变的对象,比如

adataframe[adataframe$col==something]<-$self+1 
Run Code Online (Sandbox Code Playgroud)

Mat*_*wle 34

尝试包data.table及其:=运算符.它非常快,非常短.

DT[col1==something, col2:=col3+1]
Run Code Online (Sandbox Code Playgroud)

第一部分col1==something是子集.您可以在此处放置任何内容并使用列名称,就好像它们是变量一样; 即,无需使用$.然后第二部分col2:=col3+1将RHS分配给该子集内的LHS,其中列名称可以分配为好像它们是变量.:=是通过引用分配.任何对象的任何副本获得,所以在比快<-,=,withintransform.

此外,即将在V1.8.1中实现的一个最终目标j的语法允许:=j这样与它相结合by,看问题:当我应该使用:=运营商data.table.

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

  • @ tomas -t`:=`不是基本语言运算符.R未使用和未定义,但可以定义. (3认同)

42-*_*42- 15

你应该更加关注Gabor Grothendeick(而不仅仅是在这个例子中.)incMatt Asher博客上引用的函数可以满足你的所有要求:

(明显的扩展也有效.)

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

编辑:在我第一次评论中缺乏批准的暂时烦恼之后,我接受了添加另一个函数参数的挑战.提供了数据帧的一部分的一个参数,它仍然会将值的范围增加一.到目前为止,在中缀二元运算符上只进行了非常轻微的测试,但我认为它不适用于任何只接受两个参数的函数:

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

(有罪的承认:从返回值的传统R视角来看,这在某种程度上"感觉不对".)早期对该inc功能的测试如下:

df <- data.frame(a1 =1:10, a2=21:30, b=1:2)
 inc <- function(x) {
   eval.parent(substitute(x <- x + 1))
 }

#---- examples===============>

> 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
Run Code Online (Sandbox Code Playgroud)

  • 有些人只是不满意. (10认同)

Ram*_*ath 6

这是你可以做的.我们假设您有一个数据帧

df = data.frame(x = 1:10, y = rnorm(10))
Run Code Online (Sandbox Code Playgroud)

并且你希望将所有增加y1.你可以通过使用来轻松完成transform

df = transform(df, y = y + 1)
Run Code Online (Sandbox Code Playgroud)


Mar*_*gan 6

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

ridx <- adataframe$col==something
adataframe[ridx,] <- adataframe[ridx,] + 1
Run Code Online (Sandbox Code Playgroud)

它不依赖于任何花哨/脆弱的解析,对于正在执行的操作是合理的表达,并且不是太冗长.也倾向于将线条分成很好的人性化解析单元,并且使用标准习语有一些吸引人的东西--R的词汇和特性已经足够我的口味了.