【问题标题】:Adding new columns to R dataframe from another, longer dataframe从另一个更长的数据帧向 R 数据帧添加新列
【发布时间】:2021-04-21 00:25:58
【问题描述】:

我有 2 个具有不同信息的数据帧(两个数据帧中只有 1 列相同:subject)。此外,其中一个数据框比另一个更长(更多列和更多行)。

所以,我有这样的事情:

# drataframe 1

subject var1 var2
101      A    B
102      C    D
103      E    F
...

# dataframe 2

subject  varW varX varY varZ
101        1    2    1    4
101        2    1    1    4
101        4    1    1    4
102        2    1    2    5
102        1    1    2    5
102        2    4    2    5
103        2    3    3    1
103        1    2    3    1
103        4    1    3    1   

请注意,每个主题在数据框 2 中重复多次,而在数据框 1 中,每个主题只出现一次。

我想要做的是将列 varYvarZ 附加到数据框 1。

我尝试使用select(选择这两列)然后inner_join(加入两个数据框)。但是,我为每个主题得到 3 行,因为每个主题在数据框 2 中重复 3 次。我希望数据框 1 中的每个主题在加入后只有 1 行,因为 varY 和 @ 中只有一个值每个主题987654328@。

换句话说,这将是我想要的输出:

subject var1 var2 varY varZ
101      A    B    1    4
102      C    D    2    5
103      E    F    3    1

【问题讨论】:

    标签: r dataframe


    【解决方案1】:

    使用library(data.table)

    df1[df2[, .SD[1], .SDcols=c("varY", "varZ"), by=subject], on="subject"]
    

    或者(来自@thelatemail 的评论),

    df2[, .(subject, varY, varZ)][df1, on=.(subject), mult="first"]
    

    数据:

    df1 = fread("
    subject var1 var2
    101      A    B
    102      C    D
    103      E    F
                ")
    
    df2 = fread("
    subject  varW varX varY varZ
    101        1    2    1    4
    101        2    1    1    4
    101        4    1    1    4
    102        2    1    2    5
    102        1    1    2    5
    102        2    4    2    5
    103        2    3    3    1
    103        1    2    3    1
    103        4    1    3    1 
    ")
    

    【讨论】:

    • 替代方案,避免分组by= - df2[, .(subject, varY, varZ)][df1, on=.(subject), mult="first"]
    【解决方案2】:

    如果selected 列具有唯一值,则使用distinct 并通过“主题”进行连接

    library(dplyr)
    distinct(df2, subject, varY, varZ) %>%
         right_join(df1) %>%
         select(names(df1), everything())
    

    -输出

    #   subject var1 var2 varY varZ
    #1     101    A    B    1    4
    #2     102    C    D    2    5
    #3     103    E    F    3    1
    

    数据

    df1 <- structure(list(subject = 101:103, var1 = c("A", "C", "E"),
    var2 = c("B", 
    "D", "F")), class = "data.frame", row.names = c(NA, -3L))
    
    df2 <- structure(list(subject = c(101L, 101L, 101L, 102L, 102L, 102L, 
    103L, 103L, 103L), varW = c(1L, 2L, 4L, 2L, 1L, 2L, 2L, 1L, 4L
    ), varX = c(2L, 1L, 1L, 1L, 1L, 4L, 3L, 2L, 1L), varY = c(1L, 
    1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), varZ = c(4L, 4L, 4L, 5L, 5L, 
    5L, 1L, 1L, 1L)), class = "data.frame", row.names = c(NA, -9L
    ))
    

    【讨论】:

      【解决方案3】:

      我希望这是你想要的:

      library(dplyr)
      library(tidyr)
      
      df2 %>%
        left_join(df1, by = "subject") %>%
        select(-c(varX, varW)) %>%
        group_by(subject) %>%
        slice_head(n = 1) %>%
        relocate(subject, var1, var2)
      
      # A tibble: 3 x 5
      # Groups:   subject [3]
        subject var1  var2   varY  varZ
          <dbl> <chr> <chr> <dbl> <dbl>
      1     101 A     B         1     4
      2     102 C     D         2     5
      3     103 E     F         3     1
      
      

      数据

      df2 <- tribble(
        ~subject,  ~varW, ~varX, ~varY, ~varZ,
        101,        1,    2,    1,    4,
        101,        2,    1,    1,    4,
        101,        4,    1,    1,    4,
        102,        2,    1,    2,    5,
        102,        1,    1,    2,    5,
        102,        2,    4,    2,    5,
        103,        2,    3,    3,    1,
        103,        1,    2,    3,    1,
        103,        4,    1,    3,    1
      )
      
      df1 <- tribble(
        ~subject, ~var1, ~var2,
        101,      "A",    "B",
        102,      "C",    "D",
        103,      "E",    "F"
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-09
        • 2016-09-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-07
        • 1970-01-01
        • 2019-06-22
        相关资源
        最近更新 更多