【发布时间】:2018-06-18 03:21:03
【问题描述】:
我有一个大的data.frame 结构类似于以下示例df
df <- data.frame(id = c(rep("A",3), rep("B", 2), rep("C", 4)),
x = c(paste0(letters[1:3],1) , paste0(letters[1:2],3),
paste0(letters[1:4], 1)) ,
y = 1:9, z = 2:10 )
# id x y z
# 1 A a1 1 2
# 2 A b1 2 3
# 3 A c1 3 4
# 4 B a3 4 5
# 5 B b3 5 6
# 6 C a1 6 7
# 7 C b1 7 8
# 8 C c1 8 9
# 9 C d1 9 10
在真实数据集中有一个额外的维度(时间),并且有更多的数字列。我想通过以下方式使用dplyr 包来操作df(因为这种操作看起来很快)。
我需要将
x的y和z值减去等于b1的id == A(row = 2) 减去a3的@9876543@33@ (@9876543434) ) 和a1分别为id == C(row = 6) 和A、B和C的剩余y和z值。删除已减去的行。
生成的 data.frame 将是
# id x y z
# 1 A a1 -1 -1
# 2 A c1 1 1
# 3 B b3 1 1
# 4 C b1 1 1
# 5 C c1 2 2
# 6 C d1 3 3
在真正的data.frame 中,我有多个数字列(为简单起见,我没有显示),因此这些操作应该应用于所有列。注意x 中的代码必须引用id,因为不同的id 可以有相同的x 代码(例如A 和C)。
我找到了这个可能的解决方案:
df %>%
mutate(cond = ifelse( (id == "A" & x == "b1") | ( id == "B" & x == "a3" ) | ( id == "C" & x == "a1" ) , 1, 0 ) ) %>%
group_by(id) %>%
mutate_at(vars("y", "z"),funs(.-.[cond==1])) %>%
filter(cond == 0)
它似乎工作。更好/更快的想法?
【问题讨论】:
-
作为一个建议,第一个
mutate步骤可以通过使用您的id/x对创建一个 data.frame 来替换,然后进行内部连接。 -
会更快吗?我追求速度.. 愿意接受比我提出的更好的答案
-
应该很快。它会更简单,更不容易出错。
-
你能在答案中写下吗?我还在学习
dplyr -
您愿意接受 data.table 解决方案吗?我可以在那个包中找到一个快速的解决方案