如何在 R 中合并和合并多个数据帧?

问题描述 投票:0回答:1

我有几个数据集是长到宽转换的结果。示例数据:

data1 <- data.frame(
                   x1 = c(1, NA, NA, NA, NA, NA),          # Create example data frame
                   x2 = c(NA, 1, NA, NA, NA, NA),
                   x3 = c(NA, NA, NA, 1, 1, NA),
                   y = 11:16,
                   z = 6:1)

data2 <- data.frame(
                   x1 = c(NA, NA, 2, 2, NA, NA),          # Create example data frame
                   x2 = c(NA, NA, NA, NA, 2, NA),
                   x4 = c(NA, NA, NA, NA, NA, 2),
                   y = 11:16,
                   z = 6:1)
               
data3 <- data.frame(
                    x2 = c(3, NA, 3, NA, NA, NA),          # Create example data frame
                    x3 = c(NA, 3, NA, NA, NA, NA),
                    x5 = c(NA, NA, NA, NA, 3, 3),
                    y = 11:16,
                    z = 6:1)

  • 所有数据集具有相同的行数。
  • 所有数据集中的某些列都是相同的,例如示例中的 y 和 z。
  • 其他列仅存在于某些数据集中。有些发现于 多个数据集(此处为x1、x2、x3),其他数据集仅找到 一次(此处为 x4 和 x5)。这些列有许多 NA 和一些有效的 数值。

我想合并数据集,获得以下内容:

 datafull
  x1 x2 x3 x4 x5  y z
1  1  3 NA NA NA 11 6
2 NA  1  3 NA NA 12 5
3  2  3 NA NA NA 13 4
4  2 NA  1 NA NA 14 3
5 NA  2  1 NA  3 15 2
6 NA NA NA  2  3 16 1

所有列都应该存在,并且任何数据集中存在的任何有效值都应包含在专用列中,以替换其他数据集中的 NA(例如,查看 x1 和 x2)。

我尝试过

datasetlist <- list(data1, data2, data3)
datafull <- Reduce(function(x, y) merge(x, y, all.y=TRUE), datasetlist)  

但我得到的是

datafull
  x2  y z x3 x1 x4 x5
1  3 11 6 NA NA NA NA
2  3 13 4 NA NA NA NA
3 NA 12 5  3 NA NA NA
4 NA 14 3 NA  2 NA NA
5 NA 15 2 NA NA NA  3
6 NA 16 1 NA NA  2  3

看起来在Reduce完成的迭代合并中,新数据集中的值完全替换了旧值,即使新值是NA。

有什么办法可以避免这种情况吗?

r join merge dataset coalesce
1个回答
0
投票

编写一个函数来完成相同的任务

patch_all <- function(x){
  if (is.data.frame(x)) return(x)
  nms_x <- names(x[[1]])
  if (length(x) == 1 & is.data.frame(x[[1]]))
    return(x[[1]][, order(nms_x)])
  nms_y <- names(x[[2]])
  nms_all <- intersect(nms_x, nms_y)
  x[[2]] <- tibble::rowid_to_column(x[[1]][nms_all])|>
    dplyr::rows_patch(rowid_to_column(x[[2]][nms_all]), 'rowid') |>
    cbind(x[[1]][setdiff(nms_x, nms_y)],
          x[[2]][setdiff(nms_y, nms_x)])  |>
    select(-rowid)
  x[[1]] <- NULL
  Recall(x)
}


patch_all(lst(data1, data2, data3))
  x1 x2 x3 x4 x5  y z
1  1  3 NA NA NA 11 6
2 NA  1  3 NA NA 12 5
3  2  3 NA NA NA 13 4
4  2 NA  1 NA NA 14 3
5 NA  2  1 NA  3 15 2
6 NA NA NA  2  3 16 1
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.