【问题标题】:how to blend two columns by stubsituting NA's?如何通过存根 NA 来混合两列?
【发布时间】:2014-05-09 13:17:54
【问题描述】:

我有一个巨大的数据框,其中包含需要合并的两列。 On 可能想知道这是否不仅仅是这篇文章here 中提到的同一个问题,但我的数据框实际上不存在仅两列。还有更多(有很多 NA),我只想处理其中的两个,我猜这让它有点复杂。

这是其中的一部分:

    col1 col2
15   NA    4
16   NA    5
17   NA    5
18   NA    5
19   NA    1
20   NA   NA
21   NA   NA
22   1    NA
23   5    NA
24   2    NA
25   4    NA
26   3    NA
27   NA    2
28   NA    4
29   NA    5
30   NA    3

我需要通过替换彼此的 NA 将这些列合并为一个。当两列都包含 NA 时,不会发生任何替换(但这很明显)。

结果应该是这样的:

    col1
15   4    
16   5  
17   5  
18   5  
19   1  
20   NA 
21   NA 
22   1  
23   5  
24   2  
25   4  
26   3  
27   2  
28   4  
29   5  
30   3  

我尝试了一个丑陋的 for 循环:

for (i in 1:nrow(df)){
  if (is.na(df[i,1])==TRUE){
    df[i,1] <- df[i,2]
  }
 }
df <- df[,1]

但该代码似乎太慢了。有谁知道两个如何处理这个问题?

非常感谢!

【问题讨论】:

标签: r


【解决方案1】:

无需循环,因为您可以分配给子集:

df$col1[is.na(df$col1)] <- df$col2[is.na(df$col1)]

【讨论】:

  • 你确定这应该有效吗?我收到此消息:“要替换的项目数不是替换长度的倍数”
  • 确保每一边的方括号内都有相同的代码,如 Roland 的示例所示。即 col1 两次,而不是左侧的 col1 和右侧的 col2。
【解决方案2】:

像 SQL 这样的语言有一个名为 coalesce 的函数,它返回给定一组列表的第一个非缺失值。我在 R 中编写了一个执行此行为的函数。

coalesce<-function(...) {
    x<-lapply(list(...), function(z) {if (is.factor(z)) as.character(z) else z})
    m<-is.na(x[[1]])
    i<-2
    while(any(m) & i<=length(x)) {
        if ( length(x[[i]])==length(x[[1]])) {
            x[[1]][m]<-x[[i]][m]
        } else if (length(x[[i]])==1) {
            x[[1]][m]<-x[[i]]
        } else {
            stop(paste("length mismatch in argument",i," - found:", length( x[[i]] ),"expected:",length( x[[1]] ) ))
        }
        m<-is.na(x[[1]])
        i<-i+1
    }
    return(x[[1]])
}

你会像这样使用它

coalesce(col1,col2)

如果所有行都是 NA,你也可以添加一个默认值

coalesce(col1,col2, -9)

它返回一个新列,而不是修改任何原始列。

我尽量在this gist上保留最新版本的功能

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-27
    • 1970-01-01
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-19
    相关资源
    最近更新 更多