R- 考虑到一些被调用的数据帧可能不存在,如何 merge/bind 多个数据帧?

R- How to merge/bind several dataframes considering that some of the called dataframes might not exist?

我必须在 R 的迭代过程中 bind/merge 数据帧。在某些情况下,某些数据帧可能不存在,原因我不会在这里解释。我想知道如何在调用一些不存在的数据帧时绑定数据帧。例如,我有这些数据框:

df.R_H <- data.frame(A=c(0,4,5,6,7),
                  B=c(3,9,4,5,8),
                  C=c(1,2,4,2,6))

df.B_C <- data.frame(A=c(0,4,5,6,7),
                  B=c(3,9,4,5,8),
                  C=c(1,2,4,2,6))

df.G_H <- data.frame(A=c(0,4,5,6,7),
                  B=c(3,9,4,5,8),
                  C=c(1,2,4,2,6))

但是,在我的代码中我有这个:

df5 <- rbind(df.R_H,df.B_C,df.G_H,df.R_C)
df5

虽然 df.R_C 不存在,但我如何绑定数据框?我无法单独检查哪些数据帧存在或不存在,因为我有数百种这样的情况,即使某些数据帧不存在,我也想自动执行此操作。

您可以使用 mget() 来获取 rbind() 在环境中找到的所有数据帧。或者,对于您的示例,您可以将 x 显式传递给 mget() 作为 paste0("df", 1:4) 而不是 ls().

df1 <- data.frame(A=c(0,4,5,6,7),
                  B=c(3,9,4,5,8),
                  C=c(1,2,4,2,6))

df2 <- data.frame(A=c(0,4,5,6,7),
                  B=c(3,9,4,5,8),
                  C=c(1,2,4,2,6))

df3 <- data.frame(A=c(0,4,5,6,7),
                  B=c(3,9,4,5,8),
                  C=c(1,2,4,2,6))

df5 <- do.call(rbind, mget(ls(), mode = "list", ifnotfound = list(NULL)))
df5
#>       A B C
#> df1.1 0 3 1
#> df1.2 4 9 2
#> df1.3 5 4 4
#> df1.4 6 5 2
#> df1.5 7 8 6
#> df2.1 0 3 1
#> df2.2 4 9 2
#> df2.3 5 4 4
#> df2.4 6 5 2
#> df2.5 7 8 6
#> df3.1 0 3 1
#> df3.2 4 9 2
#> df3.3 5 4 4
#> df3.4 6 5 2
#> df3.5 7 8 6

如果你有一个拥挤的环境,这很可能,那么你可以利用 ls()pattern 参数来确保我们只通过 mget() 拉入相关数据帧。因此,如果您所有的数据框都以 df... 开头,那么您可以使用:

do.call(rbind, mget(ls(pattern = "^df*"), mode = "list", ifnotfound = list(NULL)))

另一个可能的解决方案:

library(tidyverse)

df.R_H <- data.frame(A=c(0,4,5,6,7),
                     B=c(3,9,4,5,8),
                     C=c(1,2,4,2,6))

df.B_C <- data.frame(A=c(0,4,5,6,7),
                     B=c(3,9,4,5,8),
                     C=c(1,2,4,2,6))

df.G_H <- data.frame(A=c(0,4,5,6,7),
                     B=c(3,9,4,5,8),
                     C=c(1,2,4,2,6))

map_dfr(list("df.R_H","df.B_C","df.G_H","df.R_C"), ~ if (exists(.x)) {get(.x)})

#>    A B C
#> 1  0 3 1
#> 2  4 9 2
#> 3  5 4 4
#> 4  6 5 2
#> 5  7 8 6
#> 6  0 3 1
#> 7  4 9 2
#> 8  5 4 4
#> 9  6 5 2
#> 10 7 8 6
#> 11 0 3 1
#> 12 4 9 2
#> 13 5 4 4
#> 14 6 5 2
#> 15 7 8 6