使用 dplyr 根据另一个向量替换 NA 每列

Replace NA each column based on another vector using dplyr

我正在尝试使用另一个向量替换许多列的 data.frame 中的 NA,其中给出了每列的替换值。我知道如何使用函数替换每个值,但不知道如何在另一个向量中找到该值。我正在寻找 dplyr 方法:

例如:

require(dplyr)
test <- data.frame(A = c(1,2,3,NA), B = c(4,5,NA,2), C = c(NA,2,2,NA), D = c(1,2,3,4))
replace_na <- c(A = 100, B = 200, C = 300)
# Replace with median should be replace with look up value in vector based on the name of the vector or position
test %>% mutate_each_(funs(replace(., is.na(.), median(.,na.rm = T))), names(replace_na))
expected_result <- data.frame(A = c(1,2,3,100), B = c(4,5,200,2), C = c(300,2,2,300), D = c(1,2,3,4))
> expected_result
    A   B   C  D
1   1   4 300  1
2   2   5   2  2
3   3 200   2  3
4 100   2 300  4

我们可以使用 Mapbase R

test[names(replace_na)] <- Map(function(x,y) 
      replace(x, is.na(x), y), test[names(replace_na)], replace_na)
test
#    A   B   C D
#1   1   4 300 1
#2   2   5   2 2
#3   3 200   2 3
#4 100   2 300 4

tidyverse

library(tidyverse)
test %>% 
   select_at(names(replace_na)) %>%
   map2_df(., replace_na, ~replace(., is.na(.), .y)) %>%
   bind_cols(., select_at(test, setdiff(names(test), names(replace_na))))
# A tibble: 4 x 4
#      A     B     C     D
#  <dbl> <dbl> <dbl> <dbl>
#1     1     4   300     1
#2     2     5     2     2
#3     3   200     2     3
#4   100     2   300     4

set 来自 data.table

library(data.table)
setDT(test)
for(j in names(replace_na)){
  set(test, i = which(is.na(test[[j]])), j = j, value = replace_na[j])
 }

test
#     A   B   C D
#1:   1   4 300 1
#2:   2   5   2 2
#3:   3 200   2 3
#4: 100   2 300 4

就像使用 tidyr-package:

中的 replace_na 函数一样简单
library(tidyr)
test %>% replace_na(as.list(replacements))

输出:

    A   B   C D
1   1   4 300 1
2   2   5   2 2
3   3 200   2 3
4 100   2 300 4

此函数需要一个列表,其中包含您要替换 NA 的列。因此,可以仅替换选定的列。示例:

replacements2 <- list(B = 200, C = 300)
test %>% replace_na(replacements2)

输出:

   A   B   C D
1  1   4 300 1
2  2   5   2 2
3  3 200   2 3
4 NA   2 300 4

如您所见,只有 B 和 C 列的 NA 被替换。

数据:

test <- data.frame(A = c(1,2,3,NA), B = c(4,5,NA,2), C = c(NA,2,2,NA), D = c(1,2,3,4))
replacements <- c(A = 100, B = 200, C = 300)