2016-09-21 108 views
2

可能很简单但棘手的问题,特别是对于较大的数据集。给定两个dataframes(df1df2)相同尺寸如下的:在两个数据框中有条件地替换NA R

head(df1) 
      a   b c 
1 0.8569720 0.45839112 NA 
2 0.7789126 0.36591578 NA 
3 0.6901663 0.88095485 NA 
4 0.7705756 0.54775807 NA 
5 0.1743111 0.89087819 NA 
6 0.5812786 0.04361905 NA 

head(df2) 
      a   b c 
1 0.21210312 0.7670091 NA 
2 0.19767464 0.3050934 1 
3 0.08982958 0.4453491 2 
4 0.75196925 0.6745908 3 
5 0.73216793 0.6418483 4 
6 0.73640209 0.7448011 5 

怎么能找到的所有列,其中if(all(is.na(df1)),在这种情况下c,去df2,并设置所有值在匹配列(c)到NAs

所需的输出

head(df3) 
      a   b c 
1 0.21210312 0.7670091 NA 
2 0.19767464 0.3050934 NA 
3 0.08982958 0.4453491 NA 
4 0.75196925 0.6745908 NA 
5 0.73216793 0.6418483 NA 
6 0.73640209 0.7448011 NA 

我的实际dataframes有超过140000列。

+0

你可以使用此代码“空”列: 'colSums(is.na(x))== nrow(x))',这在这里实现:https://github.com/sjPlot/sjmisc/blob/master/R/is_empty.R#L94 – Daniel

+2

因此,'df2 [,empty_cols(df1)] < - NA'应该工作(现在不能测试,从手机发表评论)。 – Daniel

回答

3

我们可以在否定逻辑矩阵(is.na(df1)),否定用colSums(!) the VECTOR`使0非NA元素为TRUE和所有其他FALSE,用这个子集的“DF2”列,并为其分配到NA。

df2[!colSums(!is.na(df1))] <- NA 
df2 
#   a   b c 
#1 0.21210312 0.7670091 NA 
#2 0.19767464 0.3050934 NA 
#3 0.08982958 0.4453491 NA 
#4 0.75196925 0.6745908 NA 
#5 0.73216793 0.6418483 NA 
#6 0.73640209 0.7448011 NA 

或者另一种选择是遍历的列,并检查元件是否all是NA创建逻辑矢量子集划分“DF2”的列和在分配给NA

df2[sapply(df1, function(x) all(is.na(x)))] <- NA 

如果这些大的数据集,另一种选择是setdata.table(应该是因为这不到位的分配更有效)

library(data.table) 
setDT(df2) 
j1 <- which(sapply(df1, function(x) all(is.na(x)))) 

for(j in j1){ 
    set(df2, i = NULL, j = j, value = NA) 
} 
+0

感谢您的这个聪明的答案。它运行良好,但需要花费时间在'dim = 4779行和141743列'的'df'上完成。 – code123

+0

@ code123我还添加了一个'data.table'解决方案。请检查是否有任何区别 – akrun