如何从其他变量填充缺失值?

时间:2015-04-18 20:36:56

标签: r dataset

我的数据集如下。

x    y 
0     
0    0
2    2
     2
     4
2
7    7

我想像这样合并x和y变量

x  
0     
0  
2  
2
4
2
7

也就是说,如果缺少x,我想用y变量值填充x变量值。如果x和y变量都没有丢失,则两个值始终相同。

4 个答案:

答案 0 :(得分:3)

只需复制缺失的y

x值即可
x <- c(0,0,2,NA,NA,2,7)
y <- c(NA,0,2,2,4,NA,7)

x[is.na(x)] <- y[is.na(x)]

答案 1 :(得分:3)

另一种变体

x = ifelse(is.na(x), y,x)

答案 2 :(得分:2)

由于您的数据已经在data.frame,但似乎:

df <- data.frame(x = c(0,0,2,NA,NA,2,7), y = c(NA,0,2,2,4,NA,7))

然后只需从列中获取更大的值:

> apply(df, 1, max, na.rm = TRUE)
[1] 0 0 2 2 4 2 7

答案 3 :(得分:2)

如果您说xy在没有缺失值时相同,则可以使用rowMeans轻松进行矢量化或使用pmax(或pmin}与do.call

相结合

您的数据

df <- data.frame(x = c(0,0,2,NA,NA,2,7), y = c(NA,0,2,2,4,NA,7))

解决方案#1

rowMeans(df, na.rm = TRUE)
## [1] 0 0 2 2 4 2 7

解决方案#2

do.call(pmax, c(df, na.rm = TRUE)) # or do.call(pmin, c(df, na.rm = TRUE))
## [1] 0 0 2 2 4 2 7

为了进行比较,对于相对较大的数据,这将仅失去@MrFlicks方法

n <- 1e5
dftest <- data.frame(x = as.vector(replicate(n, df$x)),
                     y = as.vector(replicate(n, df$y)))

library(microbenchmark)
microbenchmark(ifelse(is.na(dftest$x), dftest$y, dftest$x),
               dftest$x[is.na(dftest$x)] <- dftest$y[is.na(dftest$x)],
               apply(dftest, 1, max, na.rm = TRUE),
               rowMeans(dftest, na.rm = TRUE),
               do.call(pmax, c(dftest, na.rm = TRUE)))

# Unit: milliseconds
#                                                   expr        min         lq       mean     median         uq       max neval
#            ifelse(is.na(dftest$x), dftest$y, dftest$x)  121.16554  132.17962  188.81260  162.88925  242.37786  452.3506   100
# dftest$x[is.na(dftest$x)] <- dftest$y[is.na(dftest$x)]   32.46432   34.13887   45.88664   36.78413   42.72560  138.9821   100
#                    apply(dftest, 1, max, na.rm = TRUE) 2284.13414 2428.15899 2554.03813 2501.33842 2605.78132 3567.5111   100
#                         rowMeans(dftest, na.rm = TRUE)   40.04718   44.39996   61.89289   48.16691   54.88427  189.2017   100
#                 do.call(pmax, c(dftest, na.rm = TRUE))   44.68004   45.66772   52.64246   46.43867   50.02424  149.1624   100