[英]Merge Two Lists of Data Frames by ID and DATE in R
我需要通過兩個關鍵變量ID和DATE合並兩個數據幀列表。 這是我擁有的數據的示例:
names1 <- c("df1", "df2")
mydf1 <- data.frame(ID=c(115477, 115477), DATE=c("2012-01-31","2012-02- 29"), SCORE =c(677,635))
mydf2 <- data.frame(ID=c(22319, 22319), DATE=c("2011-09-30","2011-10-31"), SCORE = c(621,630))
list1 <- list(mydf1,mydf2)
names(list1) <- names1
names2 <- c("df_auto1", "df_auto2")
mydf_auto1 <- data.frame(ID=c(22319, 22319),DATE=c("2011-09-30","2011-10-31") , Fprice =c(8708,8708))
mydf_auto2 <- data.frame(ID=c(115477, 115477), DATE=c("2012-01-31","2012-02-29"), Fprice = c(NA,6543))
list2 <- list(mydf_auto1,mydf_auto2)
names(list2) <- names2
我嘗試使用Map函數,但輸出混亂。 這是我嘗試做的事情:
V <-Map(merge, list1, list2,MoreArgs=list(by=c('ID','DATE'), all=TRUE))
for (i in seq_along(V)) {
write.csv(V[[i]], paste0("merge_",i, ".csv"))
}
作為最終輸出,我想獲得一個ID = 115477的數據幀,並填充完整的變量,例如DATE,SCORE和Fprice; 另一個ID為22319並已完全填充的數據框。 例如,對於ID = 115477,我想獲得:
ID DATE SCORE Fprice
115477 2012-01-31 677 NA
115477 2012-02-29 635 6543
有人知道我在做什么錯嗎? 謝謝您的幫助。
這是一個tidyverse
方法:
library(tidyverse);
list(bind_rows(list1), bind_rows(list2)) %>%
reduce(function(x, y) full_join(x, y, by = c("ID", "DATE"))) %>%
filter(ID %in% c(115477))
# ID DATE SCORE Fprice
#1 115477 2012-01-31 677 NA
#2 115477 2012-02-29 635 6543
說明:對於每個list
我們將行綁定到單個data.frame
; 我們將兩個折疊的data.frame
收集到一個list
,然后通過"ID"
和"DATE"
執行外部data.frame
; 我們使用dplyr::filter
提取感興趣的行(此處ID==115477
)。
最終結果是一個包含兩個數據幀的列表,每個數據幀的結果是list2
中的第 j 個元素外部連接到list1
第 i 個元素。
注意: mydf1
中第二個DATE
元素中有一個錯字,下面對此進行了更正。 我的回答取決於list1
和list2
的內容,這些內容具有按相同順序包含相同ID
值的數據幀。 按照OP的安排,將mydf_auto2
設置為合並到mydf1
; 而mydf_auto2
應合並到mydf2
基於共享相同的這兩個數據幀ID
值。 我修改list2
內的順序以產生所需的輸出。
# create first list of data frames
names1 <- c("df1", "df2")
# note the extra spacing in "2012-02-29" has been corrected
mydf1 <- data.frame(ID=c(115477, 115477), DATE=c("2012-01-31","2012-02-29"), SCORE =c(677,635))
mydf2 <- data.frame(ID=c(22319, 22319), DATE=c("2011-09-30","2011-10-31"), SCORE = c(621,630))
list1 <- list(mydf1,mydf2)
names(list1) <- names1
# create second list of data frames
names2 <- c("df_auto1", "df_auto2")
# here is where I relabel the data frames
# to sync with `mydf1` and `mydf2` based on
# the `ID` values contained in `mydf_auto1` and `mydf_auto2`
mydf_auto1 <- data.frame(ID=c(115477, 115477), DATE=c("2012-01-31","2012-02-29"), Fprice = c(NA,6543))
mydf_auto2 <- data.frame(ID=c(22319, 22319),DATE=c("2011-09-30","2011-10-31") , Fprice =c(8708,8708))
list2 <- list(mydf_auto1,mydf_auto2)
names(list2) <- names2
# merge the list of data frames together
merged.list.of.dfs <-
mapply( FUN = function( i, j )
merge( x = i
, y = j
, by = c( "ID", "DATE" )
, all = TRUE )
, list1
, list2
, SIMPLIFY = FALSE )
# view results
merged.list.of.dfs
# $df1
# ID DATE SCORE Fprice
# 3 115477 2012-01-31 677 NA
# 4 115477 2012-02-29 635 6543
#
# $df2
# ID DATE SCORE Fprice
# 1 22319 2011-09-30 621 8708
# 2 22319 2011-10-31 630 8708
# end of script #
您進行merge
會更容易,然后分別提取所需的ID
names1 <- c("df1", "df2")
mydf1 <- data.frame(ID=c(115477, 115477), DATE=c("2012-01-31","2012-02-29"), SCORE =c(677,635))
mydf2 <- data.frame(ID=c(22319, 22319), DATE=c("2011-09-30","2011-10-31"), SCORE = c(621,630))
# Note the change to use of rbind instead of list
list1 <- rbind(mydf1, mydf2)
names2 <- c("df_auto1", "df_auto2")
mydf_auto1 <- data.frame(ID=c(22319, 22319),DATE=c("2011-09-30","2011-10-31") , Fprice =c(8708,8708))
mydf_auto2 <- data.frame(ID=c(115477, 115477), DATE=c("2012-01-31","2012-02-29"), Fprice = c(NA,6543))
list2 <- rbind(mydf_auto1,mydf_auto2)
df <- merge(list1, list2, by = c("ID", "DATE"))
df[df$ID == 115477,]
df[df$ID == 22319, ]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.