不要使用data.table自动返回by-columns

时间:2018-05-08 17:21:31

标签: r data.table

示例数据:

dt = data.table(a=c(10,20,30,40),b=c(40,30,20,10),c=c(0,0,1,1))
rank_a = dt[,rank(a)]
rank_a
  

[1] 1 2 3 4

这会返回我想要的内容。但是,如果我添加一个by语句,

rank_a = dt[,rank(a),by=c]

...然后它返回一个完整的数据框,包括by列“c”,而不仅仅是我想要的答案。

如何解决此问题?

2 个答案:

答案 0 :(得分:2)

删除一个或多个" by"的通用解决方案列可以使用mget +链接:

dt = data.table(a=c(10,20,30,40),b=c(40,30,20,10),c=c(0,0,1,1),d=c(0,0,0,1))
dt
#     a  b c d
# 1: 10 40 0 0
# 2: 20 30 0 0
# 3: 30 20 1 0
# 4: 40 10 1 1

by.cols = c("c", "d")

# group by one or multiple columns without returning the "group by" columns
# (includes code of @Frank now, see comment)
dt[, .(rank=rank(a)),by = by.cols] [, -(1:length(by.cols))]
#    rank
# 1:    1
# 2:    2
# 3:    1
# 4:    1
#
# OLD code (before including the code snippets from @Frank)
# dt[, .(rank = rank(a)),by=mget(by.cols)] [, -(1:length(by.cols))]

不漂亮,但正在工作。

PS:有没有更好的方法从名称存储在字符向量中的data.table中排除列?

答案 1 :(得分:1)

它返回其他列,因为它们是理解输出所必需的。例如,如果您有数据集:

a    b
1    1
1    2
2    3
2    4

..然后你跑:

dt[, sum(b), a]

输出如下:

V1    a
3     1
7     2

这是有道理的,因为没有" a"列,输出没有任何意义,因为你不知道哪些V1值对应于哪个" a"分组。如果你真的想在这样的操作之后摆脱列,你可以用像 dt[, sum(b), a][, V1]

或作为带有

的data.table
dt[, sum(b), a][, .(V1)]