【问题标题】:merge data frames to eliminate missing observations合并数据框以消除缺失的观察结果
【发布时间】:2013-04-05 00:25:32
【问题描述】:

我有两个数据框。一个 (df1) 包含所有感兴趣的列和行,但包括缺失的观察结果。另一个 (df2) 包括用于代替缺失观测值的值,并且仅包括在df1 中至少存在一个NA 的列和行。我想以某种方式合并这两个数据集以获得desired.result

这似乎是一个很容易解决的问题,但我是在画一个空白。我无法让merge 工作。也许我可以写嵌套的for-loops,但还没有这样做。我也试过aggregate几次。我有点害怕发布这个问题,担心我的R 卡可能会被吊销。抱歉,如果这是重复的。我在这里和谷歌进行了相当深入的搜索。谢谢你的任何建议。最好使用 base R 中的解决方案。

df1 = read.table(text = "
  county year1 year2 year3
    aa     10    20   30
    bb      1    NA    3
    cc      5    10   NA
    dd    100    NA  200
", sep = "", header = TRUE)

df2 = read.table(text = "
  county year2 year3
    bb      2   NA
    cc     NA   15
    dd    150   NA
", sep = "", header = TRUE)

desired.result = read.table(text = "
  county year1 year2 year3
    aa     10    20   30
    bb      1     2    3
    cc      5    10   15
    dd    100   150  200
", sep = "", header = TRUE)

【问题讨论】:

    标签: r merge


    【解决方案1】:

    aggregate 可以这样做:

    aggregate(. ~ county,
              data=merge(df1, df2, all=TRUE), # Merged data, including NAs
              na.action=na.pass,              # Aggregate rows with missing values...
              FUN=sum, na.rm=TRUE)            # ...but instruct "sum" to ignore them.
    ##   county year2 year3 year1
    ## 1     aa    20    30    10
    ## 2     bb     2     3     1
    ## 3     cc    10    15     5
    ## 4     dd   150   200   100
    

    【讨论】:

    • FUN=Filter, f = Negate(is.na) 将是该功能的另一种选择(将保留重复,如果 OP 规范正确,则无论如何都不应该发生这种情况)
    • 优秀 - 一个很好的例子,说明 base R 如何拥有许多非常简洁且易于解释的函数,这些函数经常被忽视。
    • 谢谢。很好的答案。虽然,我认为在 na.pass 之后需要有一个逗号。我尝试编辑帖子并添加逗号,但我猜编辑必须超过一个字符。
    • @MarkMiller - 我现在已经修好了。
    • @MarkMiller 下一次,编辑评论文本,说出你在做什么。 # (added comma) Aggregate rows...。让您超过字符数限制,并减少“拒绝”票数。
    【解决方案2】:

    这样就可以了:

    m <- merge(df1, df2, by="county", all=TRUE)
    
    dotx <- m[,grepl("\\.x",names(m))]
    
    doty <- m[,grepl("\\.y",names(m))]
    
    dotx[is.na(dotx)] <- doty[is.na(dotx)]
    
    names(dotx) <- sapply(strsplit(names(dotx),"\\."), `[`, 1)
    
    result <- cbind(m[,!grepl("\\.x",names(m)) & !grepl("\\.y",names(m))], dotx)
    

    检查:

    > result
      county year1 year2 year3
    1     aa    10    20    30
    2     bb     1     2     3
    3     cc     5    10    15
    4     dd   100   150   200
    

    【讨论】:

      【解决方案3】:

      另一个选项取消reshape2 并以长格式工作:

      library(reshape2)
      ## reshape to long format
      df1.m <- melt(df1)
      df2.m <- melt(df2)
      ## get common values
      idx <- df1.m$county %in% df2.m$county & 
             df1.m$variable%in% df2.m$variable
      ## replace NA values 
      df1.m[idx,]$value <- ifelse(is.na(df1.m[idx,]$value),
                                  df2.m$value , 
                                  df1.m[idx,]$value)
      ## get the wide format
      dcast(data=df1.m,county~variable)
      
        county year1 year2 year3
      1     aa    10    20    30
      2     bb     1     2     3
      3     cc     5    10    15
      4     dd   100   150   200
      

      【讨论】:

      • 你的回答很笼统。例如,如果我在第 1 年将 aa 县的 10 更改为 NA 并从 df2 中删除第 3 年,它仍然有效。
      • @MarkMiller 是的,因为它受益于仅使用县作为 id(键)的长格式,其他列只是变量。
      猜你喜欢
      • 2018-08-17
      • 1970-01-01
      • 2015-04-10
      • 2013-07-12
      • 2018-01-07
      • 1970-01-01
      • 1970-01-01
      • 2020-03-26
      • 2015-07-01
      相关资源
      最近更新 更多