【发布时间】:2013-03-28 00:25:13
【问题描述】:
我最近一直在处理更大的数据集,并开始学习并迁移到 data.table 以提高聚合/分组的性能。我无法按预期对某些表达式或函数进行分组。这是我遇到问题的基本分组操作示例。
library(data.table)
category <- rep(1:10, 10)
value <- rnorm(100)
df <- data.frame(category, value)
dt <- data.table(df)
如果我想简单地按类别计算每个组的平均值。这很容易工作。
dt[,mean(value),by="category"]
category V1
1: 1 -0.67555478
2: 2 -0.50438413
3: 3 0.29093723
4: 4 -0.41684790
5: 5 0.33921764
6: 6 0.01970997
7: 7 -0.23684245
8: 8 -0.04280998
9: 9 0.01838804
10: 10 0.44295978
如果我尝试使用 scale 函数,甚至是从自身减去值的简单表达式,我会遇到问题。分组被忽略,我将函数/表达式应用于每一行。以下按类别返回所有 100 行而不是 10 行。
dt[,scale(value),by="category"]
dt[,value-mean(value),by="category"]
我认为将比例重新创建为返回数值向量而不是矩阵的函数可能会有所帮助。
zScore <- function(x) {
z=(x-mean(x,na.rm=TRUE))/sd(x,na.rm = TRUE)
return(z)
}
dt[,zScore(value),by="category"]
category V1
1: 1 -1.45114132
2: 1 -0.35304528
3: 1 -0.94075418
4: 1 1.44454416
5: 1 1.39448268
6: 1 0.55366652
....
97: 10 -0.43190602
98: 10 -0.25409244
99: 10 0.35496694
100: 10 0.57323480
category V1
这还会返回应用于所有行 (N=100) 并忽略分组的 zScore 函数。为了让 scale() 或自定义函数像上面使用 mean() 时那样使用分组,我缺少什么?
【问题讨论】:
-
mean返回 1 个值。scale函数为每个输入返回一个缩放值。也就是说,scale(1:5)给出了 5 个值。mean(1:5)给出 1 个值。这有助于理解您的问题吗? -
你在
grouped变量上应用的函数应该返回1个值而不是向量。 -
这正是问题所在。我试图以使用 ddply 的方式使用 data.table。我将如何使用 data.table 等效地实现以下目标。在ddply?
ddply(df,"category",transform, zscorebycategory=zScore(value)) -
@Aaron
dt[,zscorebycategory:=zScore(value),by=category]我不明白你在哪里看到问题? -
@Roland 你是对的。我没有完全意识到 := 的行为有点不同并直接更新表。当我在期望手动将其分配给 dt 之前运行它时。它现在正在工作。非常感谢您帮我解决这个问题。
标签: r data.table