簡體   English   中英

R:根據來自另一個數據框的匹配行更新列

[英]R: Update column based on matching rows from another data frame

我有

mydf1 <- data.frame(ID = c(1,2,3,4,5), color = c("red", NA, NA, NA, "green"), name = c("tom", "dick", "harry", "steve", "mike"))
mydf2 <- data.frame(ID = c(1,2,99), color = c("red", "orange", "yellow"), name = c("tom", "dick", "Aaron"))

我想用 mydf2 中對應的顏色更新 mydf1$color ,用於匹配 ID 和名稱的任何行。 所需的輸出是將第 2 行中的顏色更新為橙色,其余部分保持原樣:

   ID  color   name
1  1   red     tom
2  2   orange  dick
3  3   <NA>    harry
4  4   <NA>    steve
5  5   green   mike

我在之前的一些帖子中嘗試了非對稱合並的解決方案,但在 mydf1.x 中我的一些字段被覆蓋。 然后我嘗試按照另一篇文章中的建議使用 match,但收到錯誤消息。 不知道為什么匹配條件不起作用。

mydf1$color <- mydf2$color[match(mydf1[c("ID", "name")], mydf2[c("ID", "name")])]

我們可以在 'ID' 和 'name' 列on使用與data.table的連接,並通過賦值( := )從第一個數據集中的第二個數據集中更新相應的 'color' 值

library(data.table)
setDT(mydf1)[mydf2, color := i.color, on = .(ID, name)]
mydf1
#   ID  color  name
#1:  1    red   tom
#2:  2 orange  dick
#3:  3   <NA> harry
#4:  4   <NA> steve
#5:  5  green  mike

match適用於vector/matrix而不是data.frame 如果我們需要使用match ,則paste每個數據集中的“ID”、“名稱”並進行match

i1 <- match(paste(mydf1$ID, mydf1$name), paste(mydf2$ID, mydf2$name), nomatch = 0)

或者使用tidyverse

library(dplyr)
mydf1 %>%
   left_join(mydf2, by = c("ID", "name")) %>%
    transmute(ID, name, color = coalesce(as.character(color.x), 
                                         as.character(color.y)))
#  ID  name  color
#1  1   tom    red
#2  2  dick orange
#3  3 harry   <NA>
#4  4 steve   <NA>
#5  5  mike  green

dplyr 1.0 版開始,您可以使用實驗性的rows_*函數。 不幸的是, rows_update不允許“內部”或“左”更新——如果有不匹配的行,它會拋出錯誤。 我們可以使用rows_upsert后跟inner_join來解決這個inner_join

rows_upsert(mydf1, mydf2, by = c("ID", "name")) %>%
  inner_join(mydf1 %>% select(ID, name))
# Joining, by = c("ID", "name")
#   ID  color  name
# 1  1    red   tom
# 2  2 orange  dick
# 3  3   <NA> harry
# 4  4   <NA> steve
# 5  5  green  mike

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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