【问题标题】:How to join (merge) data frames by different variables for each observation如何通过每个观察的不同变量连接(合并)数据框
【发布时间】:2020-10-16 11:46:35
【问题描述】:

假设我有两个如下数据框:

df1 <- data.frame(
    X = c(1,2,2),
    Y = c("a","b","c"),
    Z = c(10,20,30)
)

df2 <- data.frame(
  X = c(1,2,2,4),
  Y = c(NA,"b","c","d"),
  W = c(-1,-2,-3,-4)
)

我想同时使用 X 和 Y 在 df2 上加入 df1。但对于第一次观察,我只使用 X。最后我想得到:

df3 <- data.frame(
  X = c(1,2,2,4),
  Y = c(NA,"b","c","d"),
  W = c(-1,-2,-3,-4),
  Z = c(10,20,30,NA)
)

使用 left_join 或 full_join 无法做到这一点。

【问题讨论】:

  • 那是你的真实代码吗? df3 中缺少逗号。
  • 当你说“第一个”观察时,它是基于两个数据集上的 by 变量
  • 不是我的真实代码。在df3中包含逗号
  • 如果df2$Ysecond 元素是NA,您的预期输出是什么? (Z 会是什么?)
  • 如果其中一个答案解决了您的问题,请accept it;这样做不仅为回答者提供了一些积分,而且还为有类似问题的读者提供了一些关闭。尽管您只能接受一个答案,但您可以选择对您认为有帮助的人进行投票。 (如果仍有问题,您可能需要编辑您的问题并提供更多详细信息。)

标签: r dataframe merge left-join


【解决方案1】:

您可以分两步完成此操作。首先,使用 X 和 Y 在 df1 上左连接 df2。其次,将 Z 中的任何缺失值替换为仅基于 X 的 df1 中的相应值。但这只有在 X 中没有重复项时才有效。

df4 <- merge(df2, df1, all.x=TRUE); df4
#  X    Y  W  Z
#1 1 <NA> -1 NA # <-- this guy could not match, since Y was NA
#2 2    b -2 20
#3 2    c -3 30
#4 4    d -4 NA

ind <- df4$X[is.na(df4$Z)] # returns the indices 1 4
df4$Z[ind] <- df1$Z[ind]
df4
#  X    Y  W  Z
#1 1 <NA> -1 10
#2 2    b -2 20
#3 2    c -3 30
#4 4    d -4 NA

如果 df2$Y 包含任何重复的 X 的 NA,则解是不确定的。

【讨论】:

    【解决方案2】:

    不是最优雅的,但我不知道如何做(好)条件连接:

    full_join(df2, df1, by = c("X", "Y")) %>%
      filter(!is.na(W)) %>%
      group_by(grp = is.na(Y)) %>%
      do({
        dat <- .
        if (is.na(dat$Y[1])) {
          left_join(dat, select(df1, -Y), by = "X") %>%
            mutate(Z = coalesce(Z.x, Z.y)) %>%
            select(-starts_with("Z."))
        } else dat
      }) %>%
      ungroup() %>%
      select(-grp) %>%
      arrange(X, Y)
    # # A tibble: 4 x 4
    #       X Y         W     Z
    #   <dbl> <chr> <dbl> <dbl>
    # 1     1 <NA>     -1    10
    # 2     2 b        -2    20
    # 3     2 c        -3    30
    # 4     4 d        -4    NA
    

    【讨论】:

      猜你喜欢
      • 2015-07-25
      • 1970-01-01
      • 2021-11-14
      • 2020-08-09
      • 1970-01-01
      • 2019-05-02
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      相关资源
      最近更新 更多