将 na.fill 应用于每一列

Apply na.fill to every column

我有一个如下所示的数据集:

Col1    Col2     Col3     Col4    Col5   
   A       B        4        5       7
   G       H        5        6      NA
   H       I       NA        9       8
   K       F        9       NA      NA
   E       L       NA        8       9
   H       I        1        0      10

如何将 na.fill() 函数应用于 Col2 之后的所有列?

如果我单独做的话,会是这样的:

df$Col3<-na.fill(df$Col3, c(NA, "extend", NA))
df$Col4<-na.fill(df$Col4, c(NA, "extend", NA))
df$Col5<-na.fill(df$Col5, c(NA, "extend", NA))  

问题是我的实际数据框有超过 100 列。有没有一种快速的方法可以将此函数应用于前 2 列之后的所有列?

na.fill 处理多列。真的不需要使用 lapplymutate 等。只需在相同的列上用 运行 na.fill 的结果替换相关的列。如果你知道 ix 是什么,那么你可以用它替换第一行,这样在这个例子中我们可以交替使用 ix <- 3:5ix <- -(1:2) .

ix <- sapply(DF, is.numeric)
replace(DF, ix, na.fill(DF[ix], c(NA, "extend", NA)))

给予:

  Col1 Col2 Col3 Col4 Col5
1    A    B    4  5.0  7.0
2    G    H    5  6.0  7.5
3    H    I    7  9.0  8.0
4    K    F    9  8.5  8.5
5    E    L    5  8.0  9.0
6    H    I    1  0.0 10.0

请注意,您可以交替使用 na.approx:

replace(DF, ix, na.approx(DF[ix], na.rm = FALSE))

备注

Lines <- "Col1    Col2     Col3     Col4    Col5   
   A       B        4        5       7
   G       H        5        6      NA
   H       I       NA        9       8
   K       F        9       NA      NA
   E       L       NA        8       9
   H       I        1        0      10"
DF <- read.table(text = Lines, header = TRUE, as.is = TRUE, strip.white = TRUE)

dplyr 包中的 mutate_ 系列函数可以解决问题。

有几种方法可以做到这一点。根据您的其他列的外观,有些列可能比其他列工作得更好。以下是在不同情况下效果更好的三个版本。

# Make dummy data.
df <- data.frame(
    Col1 = LETTERS[1:6],
    Col2 = LETTERS[7:12],
    Col3 = c(4, 5, NA, 9, NA, 1),
    Col4 = c(5,6,9,NA,8,0),
    Col5 = c(7,NA,8,NA,9,10)
)

您可以将 na.fill 函数应用于名称向量指定的列。如果您想对具有特定名称部分的 select 列使用正则表达式,这将很有用。

cn <- names(df) %>%
    str_subset("[345]")    # Column names with 3, 4 or 5 in them.

result_1 <- df %>% 
    mutate_at(vars(cn),
        zoo::na.fill, c(NA, 'extend', NA)
        )

您可以将 na.fill 函数应用于任何数字列。

result_2 <- df %>%
    mutate_if(is.numeric,    # First argument is function that returns a logical vector.
        zoo::na.fill, c(NA, 'extend', NA)
        )

您可以将该函数应用于数字索引向量中指定的列。

result_3 <- df
result_3[ , 3:5] <- result_3[ , 3:5] %>%    # Just replace columns 3 through 5
    mutate_all(
        zoo::na.fill, c(NA, 'extend', NA)
        )

在这种情况下,所有三个版本应该做同样的事情。

all.equal(result_1, result_2)    # TRUE
all.equal(result_1, result_3)    # TRUE