【发布时间】:2017-03-03 04:55:29
【问题描述】:
我想将标量函数(如mean)应用于主要组,并在次要组中对值进行排名。这是我正在尝试做的示例代码:
library(data.table)
mytestdata <- data.table(name=c("tom","john","tom","john","jim","jim","jack"),
len=c(10,15,12,23,3,12,3),
group=c("a","b","a","a","a","b","b"))
mytestdata[, .SD[, .(mean(len), .N), by="name"][order(V1)], by = "group"] # I need the .N to log
这里的输出是我想要的。但是,当我尝试对每个组中的名称进行排名时,我无法获得所需的输出。
mytestdata[, .SD[, .(mean(len), .N), by="name"][order(V1), myrank := seq(1:.N)], by = "group"]
上面的代码正确地分配了排名,但将列重新排序为默认顺序(忽略order(V1),它在上一行中起作用)。我认为这与:= 不显示输出有关。有没有办法解决这个问题?
我尝试了类似的东西
mytestdata[, .(.SD[, .(mean(len), .N), by="name"][order(V1)], seq(1:.N), by = "group"]
但它会抛出一个错误,说明在j 中错误地使用了list() 方法。
编辑:我想要的输出是(排名应该在组内)(A)
group name V1 N myrank
1: a jim 3 1 1
2: a tom 11 2 2
3: a john 23 1 3
4: b jack 3 1 1
5: b jim 12 1 2
6: b john 15 1 3
编辑:为了澄清我的观点,我的原始代码,
mytestdata[, .SD[, .(mean(len), .N), by="name"][order(V1)], by = "group"]
返回按我想要的方式排序的数据表,即 (1)
group name V1 N
1: a jim 3 1
2: a tom 11 2
3: a john 23 1
4: b jack 3 1
5: b jim 12 1
6: b john 15 1
现在,我想保持这种顺序并为每个组中的名称分配等级。由于i 在data.table 中的j 之前被评估,我可以在与上面order() 相同的语句中分配排名,即,
mytestdata[, .SD[, .(mean(len), .N), by="name"][order(V1), myrank := 1:.N], by = "group"]
这会正确分配排名,即 (2)
group name V1 N myrank
1: a tom 11 2 2
2: a john 23 1 3
3: a jim 3 1 1
4: b john 15 1 3
5: b jim 12 1 2
6: b jack 3 1 1
但是,行的顺序不再与 (1) 中的相同,因为我猜是赋值运算符抑制了输出并以无序格式存储数据表。现在,要获得 (A) 形式的输出,我必须通过再次分组来重新排序行或在链接方法中分配排名列,即,
mytestdata[, .SD[, .(mean(len), .N), by="name"][order(V1), myrank := 1:.N], by = "group"][order(rank), .SD, by = "group"]
(或)
mytestdata[, .SD[, .(mean(len), .N), by="name"][order(V1)], by = "group"][, myrank := 1:.N, by = "group"]
这给出了所需的输出 (A)。虽然这两个都解决了我的问题,但我很好奇是否有一个解决方案可以消除额外的链接,因为在 (2) 中正确分配了等级,并且在 (2) 中的顺序已经正确强>(1).
【问题讨论】:
-
我认为你只是把它放在错误的地方 - 你只是想要
mytestdata[, .SD[, .(mean(len), .N), by=name][order(V1)], by=group][, rank := 1:.N, by=group][]吗? -
是的,这行得通。谢谢!有没有办法消除额外的分组只是为了排名?具体来说,我很好奇为什么
order(V1)在第一种情况下有效,但在第二种情况下似乎没有显示重新排序的行,而是在重新排序后分配排名但以原始顺序显示它们。跨度> -
嗯....我还没有看到如何避免它。让我想想
-
mytestdata[, .(mean_len = mean(len), .N, group, len), by="name"][i = order(mean_len), j = .( name, len, mean_len, rank = 1:.N), by = c("group")] -
上面代码的问题是它不会处理名字的关系
标签: r data.table