假设我有以下数据:
dt <- data.table(x=1:5, y=c(1,1,2,2,1), y.z=c(1,1,2,2,3))
我喜欢按y.z
分组。 dt
的构建方式是,对于每个不同的y.z
组,y
的所有值都应相等。我想要的结果数据表是x
的总和,以及每组'y.z'的唯一1值y
因此,有两种方法可以满足我的需求:
dt[,list(x=sum(x), y=y[1]), by=y.z]
dt[,list(x=sum(x)), by=list(y.z, y)]
# it might have performance drawback, but I assume it is minor.
由于我的懒惰,通常我会选择第二种方式,如果y类型的参数列表很长,它可以节省一些输入。即写list(y.z, y1, y2, y3,...)
而不是y1=y1[1], y2=y2[1], y3=y3[1], ...
但是,我不太确定这是不是一个好习惯。特别是如果y
中出现一些错误,以致每个组都不相同,我的方法不会触发任何错误,因此问题不会自动检测到。
最好自定义这样的功能吗?
dt[,list(x=sum(x), y=assert.identical(y)]), by=y.z]
因此,如果y
仅包含1个唯一值,则返回标量,否则可触发异常。但是,自定义函数应用起来有点不方便,因为它需要输入的内容甚至超过y=y[1]
。
我每天都遇到这种困境,无论是在R还是在SQL中,两者都无法治愈。人们在面对时通常会做些什么?
答案 0 :(得分:1)
unique.data.table
有by
个参数,而.SD
只是data.table
。
将它们组合在一起可以执行以下操作:
dt[,list(x= unique(.SD[, sum(x)], by=c("y1","y2", "y3")), by=y.z]
请注意,unique中的by
必须是字符串向量(列的名称)。这与by
)
[.data.table
的要求不同