【问题标题】:Merging two data frames according to row values根据行值合并两个数据框
【发布时间】:2014-09-08 03:08:27
【问题描述】:

我有两个数据框,每个都有相同的两列:县代码和频率。它们不相同,但一些县代码值显示在两个数据框中。像这样:

"county_code","freq"
"01011",2
"01051",1
"01073",9
"01077",1

"county_code","freq"
"01011",4
"01056",2
"01073",1
"01088",6

我想将它们合并到一个新的数据框中,这样如果县代码出现在两个数据框中,它们各自的频率就会加在一起。如果县代码只出现在一个或另一个数据框中,我想将它(及其频率)添加到新的数据框中不变。结果应如下所示:

"county_code","freq"
"01011",6
"01051",1
"01056",2
"01073",10
"01077",1
"01088",6

不必对结果进行排序。我尝试为此使用 reshape,但我不确定这是正确的方法。想法?

【问题讨论】:

    标签: r dataframe reshape


    【解决方案1】:

    将两个数据框与rbind 合并,然后使用aggregate 折叠具有相同county_code 的多行:

    aggregate(freq~county_code, rbind(d1, d2) , FUN=sum)
    ##   county_code freq
    ## 1        1011    6
    ## 2        1051    1
    ## 3        1073   10
    ## 4        1077    1
    ## 5        1056    2
    ## 6        1088    6
    

    (使用 MrFlick 回答中的定义。)

    【讨论】:

    • 我相信这会比任何merge 方法都快。 +1
    【解决方案2】:

    使用基本函数,您可以先执行merge(),然后再执行transform()。这是您的示例输入 data.frames

    d1 <- data.frame(
        county_code = c("1011", "1051", "1073", "1077"), 
        freq = c(2L, 1L, 9L, 1L)
    )
    
    d2 <- data.frame(
        county_code = c("1011", "1056", "1073", "1088"),
        freq = c(4L, 2L, 1L, 6L)
    )
    

    那你就这么做

    transform(merge(d1, d2, by="county_code", all=T), 
        freq = rowSums(cbind(freq.x, freq.y), na.rm=T), 
        freq.x = NULL, freq.y = NULL
     )
    

    得到

      county_code freq
    1        1011    6
    2        1051    1
    3        1056    2
    4        1073   10
    5        1077    1
    6        1088    6
    

    【讨论】:

      【解决方案3】:

      这是一种方法。我使用了rbind()merge()dplyr

      # sample data
      country <- c("01011", "01051", "01073", "01077")
      value <- c(2,1,9,1)
      foo <- data.frame(country, value, stringsAsFactors=F)
      
      
      country <- c("01011","01056","01073","01088")
      value <- c(4,2,1,6)
      foo2 <- data.frame(country, value, stringsAsFactors=F)
      
      library(dplyr)
      
      group_by(rbind_list(foo, foo2), country) %>%
      summarize(count = sum(value))
      
      ana
      
        country count
      1   01011     6
      2   01051     1
      3   01056     2
      4   01073    10
      5   01077     1
      6   01088     6
      

      我的另一个想法如下。

      ana2 <- merge(foo, foo2, all = TRUE, by = "country") 
      
        country value.x value.y
      1   01011       2       4
      2   01051       1      NA
      3   01056      NA       2
      4   01073       9       1
      5   01077       1      NA
      6   01088      NA       6
      
      bob2 <- ana2 %>%
              rowwise() %>%
              mutate(count = sum(value.x,value.y, na.rm = TRUE))
      
        country value.x value.y count
      1   01011       2       4     6
      2   01051       1      NA     1
      3   01056      NA       2     2
      4   01073       9       1    10
      5   01077       1      NA     1
      6   01088      NA       6     6
      

      【讨论】:

      • 听起来很有道理,但“%>%”在做什么呢?
      • 这是您在 dplyr 中使用的运算符。您可能会发现this link 很有用。
      • 因为我刚刚没有安装dplyr,所以我不确定,但看起来您在第一个示例中对两列都进行了合并。如果是这样,如果两个数据帧中存在相同的行,这仍然会失败。要看到这一点,请将value 的第一个定义更改为value &lt;- c(4,1,9,1)merge 默认不会重复 country == "01011" 的行,因此结果将不正确。
      • @MatthewLundberg 感谢您的建议。由于您昨天删除了您的评论,我回到了最初的想法。我测试了你的想法并确认我应该在这里使用 rbind。非常感谢您的支持。我会修改我上面的建议。
      猜你喜欢
      • 2022-01-20
      • 2016-01-06
      • 2023-01-13
      • 2019-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-28
      • 2020-09-04
      相关资源
      最近更新 更多