合并两个数据帧列表

时间:2019-04-30 14:59:51

标签: r list merge lapply

我有两个数据帧列表。每个列表有6个数据帧。 数据框具有相同的列,但在list1中,数据框具有从2015年到2017年的信息,而list2中的框具有2018年的信息。如下所示

List1 $ A

Name Value  Year
AAA  123   2015
BBB  456   2016
CCC  789   2017
AAA  543   2018

List2 $ A

Name Value  Year
AAA  543    2018
BBB  248    2018

我想合并两个列表中的数据框。因此,最后我只想提供一个包含所有年份所有信息的数据框列表。

list1中的某些数据框已经具有2018的信息,因此当我将其与其他数据框合并时,我希望替换那些2018值。

Newlist $ A

Name Value  Year
AAA  123    2015
BBB  456    2016
CCC  789    2017
AAA  543    2018
BBB  248    2018

我尝试过但是没用

data<- lapply(list1,list2, function (x,y) merge(x,y))

我该怎么做?

2 个答案:

答案 0 :(得分:0)

dput中包含一个数据样本总是有帮助的,但这是在没有数据确认的情况下进行的尝试:

library(tidyverse)

map2(list1, list2, ~bind_rows(.y, .x) %>% group_by(Name, Year) %>% slice(1))

我们将行绑定(首先用list2绑定,然后按NameYear分组,并用slice进行第一个匹配,该匹配应采用第一个值从第二个数据帧开始的任何Name / Year重复测量。

答案 1 :(得分:0)

我们可以首先将所有内容绑定到一个较长的数据框中,并删除"2018"的条目(如果列表2中有条目,则该条目首先出现)。

要执行此操作,我们可以在添加ID列后list rbind列表,然后"2018"将它们by删除,这些ID以后可以帮助删除列表1中包含{{1 }} / ave,但将那些未出现的内容保留在列表2中。

后者的窍门是给我们一个rev(seq_along(x))

为证明我已经创建了可能与您的数据相似的示例数据。

# list the lists
L <- list(L1=L1, L2=L2)

# add id column to sublists
L <- lapply(seq(L), function(x) 
  Map(`[<-`, L[[x]], "list", value=substr(names(L)[x], 2, 2)))

# rbind lists to long data frame
d <- do.call(rbind, unlist(L, recursive=FALSE))

# remove 2018 duplicates of list L1, keep if no 2018 in list L2
do.call(rbind, by(d, d$name, function(y) {
  i <- cbind(y, id=ave(y$year, y$year, FUN=function(z) rev(seq_along(z))))
  i[!i$id == 2, ]
  }))

结果

#        name value year list id
# A.A.1     A   998 2015    1  1
# A.A.4     A   456 2016    1  1
# A.A.7     A   312 2017    1  1
# A.A.13    A   478 2018    2  1
# B.A.2     B  1592 2015    1  1
# B.A.5     B  1072 2016    1  1
# B.A.8     B   673 2017    1  1
# B.A.21    B   445 2018    2  1
# C.A.3     C   957 2015    1  1
# C.A.6     C   199 2016    1  1
# C.A.9     C  2165 2017    1  1
# C.A.31    C   342 2018    2  1
# D.B.1     D   877 2015    1  1
# D.B.4     D   876 2016    1  1
# D.B.7     D   482 2017    1  1
# D.B.13    D  1077 2018    2  1
# E.B.2     E   370 2015    1  1
# E.B.5     E  1475 2016    1  1
# E.B.8     E   768 2017    1  1
# E.B.11    E   385 2018    1  1  <- this stems from list 1!
# F.B.3     F   421 2015    1  1
# F.B.6     F   930 2016    1  1
# F.B.9     F  1105 2017    1  1
# F.B.31    F  1836 2018    2  1

数据

l1 <- list(A = structure(list(name = structure(c(1L, 2L, 3L, 1L, 2L, 
3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("A", "B", "C"), class = "factor"), 
    value = c(1371, 565, 363, 633, 404, 106, 1512, 95, 2018, 
    63, 1305, 2287), year = c(2015L, 2015L, 2015L, 2016L, 2016L, 
    2016L, 2017L, 2017L, 2017L, 2018L, 2018L, 2018L)), class = "data.frame", row.names = c(NA, 
-12L)), B = structure(list(name = structure(c(1L, 2L, 3L, 1L, 
2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L), .Label = c("D", "E", "F"), class = "factor"), 
    value = c(1389, 279, 133, 636, 284, 2656, 2440, 1320, 307, 
    1781, 172, 1215), year = c(2015L, 2015L, 2015L, 2016L, 2016L, 
    2016L, 2017L, 2017L, 2017L, 2018L, 2018L, 2018L)), class = "data.frame", row.names = c(NA, 
-12L)))

L2 <- list(A = structure(list(name = structure(1:3, .Label = c("A", 
"B", "C"), class = "factor"), value = c(1895, 430, 257), year = c(2018, 
2018, 2018)), class = "data.frame", row.names = c(NA, -3L)), 
    B = structure(list(name = structure(c(1L, 3L), .Label = c("D", 
    "E", "F"), class = "factor"), value = c(1763, 640), year = c(2018, 
    2018)), row.names = c(1L, 3L), class = "data.frame"))

L2$B <- L2$B[-2, ]  # remove intentionally value