R 如何在data.table';谁是小组成员?
我想对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
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)]