[英]Speading manipulation on data.frame with dplyr in R
我有一個像以下示例df
結構的大型data.frame
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
(因為在這些操作中它看起來很快)。
對於id == A
( row = 2
),我需要減去x
的y
和z
值等於b1
,對於id == B
( row = 4
)減去a3
,對於id == C
( row = 6
)減去a1
分別來自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)
它似乎工作。 更好/更快的想法?
如果您對data.table
解決方案data.table
開放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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.