【问题标题】:How to properly merge a variable by group from another data frame?如何从另一个数据框中按组正确合并变量?
【发布时间】:2020-08-13 13:54:28
【问题描述】:

我有两个数据集——一个是基线,另一个是后续数据集。

DF1 是具有 id、日期、score1、score2、level 和 Grade 的基线(横截面)数据。 DF2 有 id、date、score1 和 score2,格式很长,每个 id 有多行。

 df1 <- as.data.frame(cbind(id = c(1,2,3),
                 date = c("2020-06-03","2020-07-02","2020-06-11"),
                 score1 =c(6,8,5),
                 score2=c(1,1,6),
                 baselevel=c(2,2,2),
                 basegrade=c("B","B","A")))

 df2 <- as.data.frame(cbind(id =c(1,1,1,1,2,2,2,3,3,3),
                  date = c("2020-06-10","2020-06-17","2020-06-24",
                  "2020-07-01", "2020-07-03", "2020-07-10","2020-07-17", "2020-06-14",
                  "2020-06-22", "2020-06-29"),
                  score1 = c(3,1,7,8,8,6,5,5,3,5),
                  score2 = c(1,4,5,4,1,1,2,6,7,1)) )

这就是我想要合并两个 dfs 的结果。

 id      date      score1  score 2  baselevel   basegrade
 1    2020-06-03    6       1         2           "B"
 1    2020-06-10    3       1         2           "B"
 1    2020-06-17    1       4         2           "B"
 1    2020-06-24    7       5         2           "B"
 1    2020-07-01    8       4         2           "B"
 2    2020-07-02    8       1         2           "B"
 2    2020-07-03    8       1         2           "B"
 2    2020-07-10    6       1         2           "B"
 2    2020-07-17    5       2         2           "B"
 3    2020-06-11    5       6         1           "A"  
 3    2020-06-14    5       6         1           "A" 
 3    2020-06-22    3       7         1           "A" 
 3    2020-06-29    5       1         1           "A" 

我在下面使用合并尝试了两个不同的代码,但我仍然得到 NAs .. 我在这里缺少什么? 任何帮助将不胜感激!

dfcombined1 <- merge(df1, df2, by=c("id","date"), all= TRUE)
dfcombined2 <- merge(df1, df2, by=intersect(names(df1), names(df2)), all= TRUE)

【问题讨论】:

    标签: r dataframe dplyr merge


    【解决方案1】:

    您可以在dplyr 中使用bind_rows()。

    library(dplyr)
    library(tidyr)
    
    bind_rows(df1, df2) %>%
      group_by(id) %>%
      fill(starts_with("base"), .direction = "updown") %>%
      arrange(date, .by_group = T)
    
    # # A tibble: 13 x 6
    # # Groups:   id [3]
    #    id    date       score1 score2 baselevel basegrade
    #    <chr> <chr>      <chr>  <chr>  <chr>     <chr>    
    #  1 1     2020-06-03 6      1      2         B        
    #  2 1     2020-06-10 3      1      2         B        
    #  3 1     2020-06-17 1      4      2         B        
    #  4 1     2020-06-24 7      5      2         B        
    #  5 1     2020-07-01 8      4      2         B        
    #  6 2     2020-07-02 8      1      2         B        
    #  7 2     2020-07-03 8      1      2         B        
    #  8 2     2020-07-10 6      1      2         B        
    #  9 2     2020-07-17 5      2      2         B        
    # 10 3     2020-06-11 5      6      2         A        
    # 11 3     2020-06-14 5      6      2         A        
    # 12 3     2020-06-22 3      7      2         A        
    # 13 3     2020-06-29 5      1      2         A
    

    【讨论】:

    • 嗯,我已经加载了 dplyr,但是当我运行 rows_insert 时出现错误:找不到函数“rows_insert”
    • @JNB rows_insert() 是dplyr 1.0.0 中的新功能之一。您需要更新软件包版本。
    • @JNB 我发现bind_rows() 没问题。不需要使用rows_insert()。它对你有用吗?
    【解决方案2】:

    我想你正在寻找这个:

    library(tidyverse)
    #Code
    df1 %>% bind_rows(df2) %>% arrange(id) %>% group_by(id) %>% fill(baselevel) %>% fill(basegrade)
    

    输出:

    # A tibble: 13 x 6
    # Groups:   id [3]
       id    date       score1 score2 baselevel basegrade
       <fct> <fct>      <fct>  <fct>  <fct>     <fct>    
     1 1     2020-06-03 6      1      2         B        
     2 1     2020-06-10 3      1      2         B        
     3 1     2020-06-17 1      4      2         B        
     4 1     2020-06-24 7      5      2         B        
     5 1     2020-07-01 8      4      2         B        
     6 2     2020-07-02 8      1      2         B        
     7 2     2020-07-03 8      1      2         B        
     8 2     2020-07-10 6      1      2         B        
     9 2     2020-07-17 5      2      2         B        
    10 3     2020-06-11 5      6      2         A        
    11 3     2020-06-14 5      6      2         A        
    12 3     2020-06-22 3      7      2         A        
    13 3     2020-06-29 5      1      2         A   
    

    【讨论】:

      【解决方案3】:

      可能是双 merge。

      merge(merge(df1[-(3:4)], df2, all.y=TRUE)[-(3:4)], df1[-(2:4)], all.x=TRUE)
      #    id       date score1 score2 baselevel basegrade
      # 1   1 2020-06-10      3      1         2         B
      # 2   1 2020-06-17      1      4         2         B
      # 3   1 2020-06-24      7      5         2         B
      # 4   1 2020-07-01      8      4         2         B
      # 5   2 2020-07-03      8      1         2         B
      # 6   2 2020-07-10      6      1         2         B
      # 7   2 2020-07-17      5      2         2         B
      # 8   3 2020-06-14      5      6         2         A
      # 9   3 2020-06-22      3      7         2         A
      # 10  3 2020-06-29      5      1         2         A
      

      【讨论】:

        猜你喜欢
        • 2020-12-21
        • 2019-01-09
        • 2016-04-04
        • 1970-01-01
        • 2022-10-22
        • 2021-07-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多