示例数据:
tmp_dt <-
data.table(grp = rep(c(1,2), each = 5), a = 1:10)
# > tmp_dt
# grp a
# 1: 1 1
# 2: 1 2
# 3: 1 3
# 4: 1 4
# 5: 1 5
# 6: 2 6
# 7: 2 7
# 8: 2 8
# 9: 2 9
# 10: 2 10
我知道我可以使用.SD
:
tmp_dt[, .SD[c(2,3)], by = grp]
# grp a
# 1: 1 2
# 2: 1 3
# 3: 2 7
# 4: 2 8
我无法工作的是使用grp
按data.table
有条件地对行进行子集。例如,我希望等效于以下dplyr
代码:
tmp_dt %>%
group_by(grp) %>%
filter(if_else(grp == 1, row_number() == 3, row_number() == 2)) %>%
ungroup
# A tibble: 2 × 2
# grp a
# <dbl> <int>
# 1 1 3
# 2 2 7
答案 0 :(得分:4)
在data.table
中,您可以执行以下操作:
tmp_dt[tmp_dt[, .I[if(grp == 1) 3 else 2], grp]$V1]
# grp a
#1: 1 3
#2: 2 7
请注意data.table
中的组变量是长度为1的向量(与其他变量不同),因此您可以避免使用效率低于 if {else 的ifelse
:
tmp_dt[, length(grp), grp]
# grp V1
#1: 1 1
#2: 2 1
答案 1 :(得分:4)
对于您的示例,if else
方法可能是要走的路。
如果您想延长一点,可以使用“查找”data.table
告诉您要使用哪一行
grp_dt <- data.table(grp = c(1,2),
row = c(3,2))
tmp_dt[ grp_dt, on = "grp", a[i.row], by = .EACHI]
# tmp_dt[ grp_dt, on = "grp", .(a = a[i.row]), by = .EACHI] ## to keep column name
# grp V1
# 1: 1 3
# 2: 2 7