R 如何在data.table';谁是小组成员?

R 如何在data.table';谁是小组成员?,r,data.table,R,Data.table,我想对data.table的列应用函数,但我想考虑应用函数的组,即我想将组值作为参数传递给函数。但是,当应用函数时,我无法获取组的名称 如何获取组值?或者我应该使用不同的方法 例如: library(data.table) set.seed(369) dta <- data.table(gr = 1:5, a = rnorm(5), b = rnorm(5), c = rnor

我想对data.table的列应用函数,但我想考虑应用函数的组,即我想将组值作为参数传递给函数。但是,当应用函数时,我无法获取组的名称

如何获取组值?或者我应该使用不同的方法

例如:

library(data.table)
set.seed(369)
dta <- data.table(gr = 1:5, 
                  a = rnorm(5),  
                  b = rnorm(5),
                  c = rnorm(5),
                  d = rnorm(5))

add <- function(x, y, group){ 
  if(group == 1){
    x + y
  } else{
    x - y
  }
}

dta[, newcol := add(c, d), by = (gr)]
库(data.table)
种子(369)
差热分析
注1:我的快速绘制答案错误地建议使用
.GRP
,在这个特定示例中,它恰好返回相同的答案。根据@MichaelChirico的建议,
.BY
是合适的特殊符号

注2:感谢@Frank提供的额外反馈——我创建了一个关于
.BY
的快速实验,并再次更新了答案,以正确反映按名称引用列表中分组列的需要

看起来这个特殊的符号就是你想要的。要了解有关
.BY
和其他符号如何工作的更多信息,请在控制台中运行
帮助(“特殊符号”)
以查看文档

library(data.table)

set.seed(369)
dta <- data.table(gr = 1:5, 
                  a = rnorm(5),  
                  b = rnorm(5),
                  c = rnorm(5),
                  d = rnorm(5))

add <- function(x, y, group){ 
  if(group == 1){
    x + y
  } else{
    x - y
  }
}

dta[, newcol := add(c, d, .BY$gr), by = (gr)]

print(dta)

#    gr          a           b           c            d     newcol
# 1:  1 -0.7506434  1.08042639 -0.57234502 -0.009598695 -0.5819437
# 2:  2  0.8976528 -0.45909601 -0.08179559 -1.359655922  1.2778603
# 3:  3  0.7449628 -0.92638505 -1.11577747  0.654088229 -1.7698657
# 4:  4  0.5811869 -0.07451776 -0.50771981 -1.009298251  0.5015784
# 5:  5 -0.3270194  0.97218850  0.55705663 -0.032128474  0.5891851

这就是data.table.BY中的.BY符号的用途,它是一个列表,但恰好适用于OP的情况,因为列表(1)==1。如果名字匹配,你可以添加(c,d,.BY$gr)
或者更一般但不太容易理解的
do.call(add,c(list(c,d),.BY))
。谢谢@Frank——在一个例子中搞乱了一些其他的例子,我看到洋葱的层次比以前多了,我明白你对$gr推荐的
.BY
的看法。我当然欢迎任何其他反馈,以确保我没有在这里传播虚假信息。好的,谢谢。我想关键不在于它们必须被名称引用,而在于您通常需要访问
的一个元素。by
而不是完整的列表,例如,
dta[,sqrt(.by),by=gr]
失败,因为您无法获取列表的sqrt,所以
dta[,sqrt(.by$gr),by=gr]
dta[,sqrt(.by[[1]],by=gr]
。实际上,您可以直接引用
gr
,而不需要像
dta[,sqrt(gr),BY=gr]
那样通过
.BY
。很抱歉造成混乱;我想后者是我的推荐。现在我想知道为什么OP最初没有尝试:)是的。我也退了一步,意识到,
dta[,sqrt(gr),by=gr]
是我通常会采用的方法——现在我只是想弄清楚是否有任何情况下这不起作用。我认为这可能会出现多个分组变量和每个组更多观察值的问题?当然必须有一些,否则为什么有必要使用
.BY
特殊符号?我使用它有两个原因:为了使我的代码更可读(从某种意义上说,我可以清楚地看到我使用的是分组变量),为了使它与.BY变量无关(例如,与toString(.BY)当
j
缓慢时,作为绘图标题或
cat
-ed发送到控制台,以便我可以跟踪进度)。这里有一个例子:(search for.BY)另外,我认为在我提到的do.call模式中传递参数也很有用。
dta[, newcol := add(c, d, gr), by = (gr)]