R语言 如果不适用,则用前一列填写该列

vulvrdjw  于 2023-10-13  发布在  其他
关注(0)|答案(5)|浏览(103)

我有一个这样的数据框

df <- data.frame(v1 = 10:14, v2 = c(NA, 1, NA, 3, 6), v3 = c(1, NA, NA, 9, 4))

  v1 v2 v3
1 10 NA  1
2 11  1 NA
3 12 NA NA
4 13  3  9
5 14  6  4

我现在想用前一列的值填充NA,所以它看起来像这样:

v1 v2 v3
1 10 10  1
2 11  1  1
3 12 12 12
4 13  3  9
5 14  6  4

我知道如何手动执行此操作,就像这样:

df$v2 <- ifelse(is.na(df$v2), df$v1, df$v2)

如何对包含许多列的完整数据框自动执行此操作?

ni65a41a

ni65a41a1#

您可以从tidyr使用fill来执行此操作:

library(dplyr)
library(tidyr)

data.frame(t(df)) %>%
  fill(., names(.)) %>%
  t()

结果:

v1 v2 v3
X1 10 10  1
X2 11  1  1
X3 12 12 12
X4 13  3  9
X5 14  6  4

注:

基本上,我转置了df,向下填充每一列,然后将其转置回原始方向

jutyujz0

jutyujz02#

for (i in 2:ncol(df))
  df[,i] = ifelse(is.na(df[,i]), df[,i-1],df[,i])

这将跨NA列的条纹传播值。如果你不想这样,只需颠倒for循环声明中的索引顺序。

2skhul33

2skhul333#

另一个使用Reduceifelse的选项:

df[] <- Reduce(function(x, y) ifelse(is.na(y), x, y), df, accumulate = TRUE)

df
#  v1 v2 v3
#1 10 10  1
#2 11  1  1
#3 12 12 12
#4 13  3  9
#5 14  6  4
j2qf4p5b

j2qf4p5b4#

您可以使用apply,但请注意,输出将是一个矩阵

t(apply(df, 1, function(x){
    replace(x, is.na(x), x[cumsum(!is.na(x))][is.na(x)])
}))
#     v1 v2 v3
#[1,] 10 10  1
#[2,] 11  1  1
#[3,] 12 12 12
#[4,] 13  3  9
#[5,] 14  6  4
a7qyws3x

a7qyws3x5#

通过使用zoona.locf

data.frame(t(apply(df,1,function(x) na.locf(x))))
  v1 v2 v3
1 10 10  1
2 11  1  1
3 12 12 12
4 13  3  9
5 14  6  4

相关问题