如何填充其他变量的缺失值?
How to fill missing values from other variable?
我的数据集组成如下。
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 变量都没有缺失,则两个值始终相同。
只需复制缺少的 x
值的 y
值
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)]
另一种变体
x = ifelse(is.na(x), y,x)
由于您的数据已经在 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
如果像你说的那样 x
和 y
在没有缺失值的情况下是相同的,你可以很容易地用 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
我的数据集组成如下。
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 变量都没有缺失,则两个值始终相同。
只需复制缺少的 x
值的 y
值
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)]
另一种变体
x = ifelse(is.na(x), y,x)
由于您的数据已经在 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
如果像你说的那样 x
和 y
在没有缺失值的情况下是相同的,你可以很容易地用 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