r - 在 R 中使用 dplyr 对 data.frame 进行快速操作
问题描述
我有一个大的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
在真实数据集中有一个额外的维度(时间),并且有更多的数字列。我想通过以下方式df
使用dplyr
包进行操作(因为这种操作看起来很快)。
我需要分别从,
y
和_ _ _ _ _ _ _ _ _ _ _ _z
x
b1
id == A
row = 2
a3
id == B
row = 4
a1
id == C
row = 6
y
z
A
B
C
删除已减去的行。
结果 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)
它似乎工作。更好/更快的想法?
解决方案
如果您愿意接受data.table
解决方案,这应该很快:
library(data.table)
setDT(df)
keys <- data.table(id=c("A","B","C"), x=c("b1","a3","a1"))
onv <- c("id","x")
vars <- c("y","z")
df[df[keys, on=onv], on=onv[1], (vars) := .SD[,..vars] - mget(paste0("i.", vars))][!keys, on=onv]
# 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
推荐阅读
- java - 如何使用Java中的数组从整数转换为月份
- python - 从下表中删除 $$Units
- r - 计算R中访问的城市数量
- python - python3选择一个随机字典
- javascript - 如何清除打字稿中的类型化数组并保留其类型?
- loops - 计算移动值范围内的平均值和标准差
- android - 将 Gradle 从 2.14 升级到 4.6
- python - 从 Python 列表中删除一个 Numpy 对象
- mysql - BEFORE 触发器和 ON UPDATE CURRENT_TIMESTAMP 之间的性能差异 - MySQL
- bash - 从第二个文件 bash 有条件地读取