簡體   English   中英

在 R 中使用 dplyr 對 data.frame 進行分散操作

[英]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 (因為在這些操作中它看起來很快)。

  1. 對於id == Arow = 2 ),我需要減去xyz值等於b1 ,對於id == Brow = 4 )減去a3 ,對於id == Crow = 6 )減去a1分別來自ABC的剩余yz值。

  2. 刪除已減去的行。

結果 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代碼(例如AC )。

我找到了這個可能的解決方案:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM