R-仅使用一个非缺失值查找列,并使用唯一的非缺失值填充其缺失值

时间:2019-02-25 13:03:26

标签: r missing-data mutate

我有一个数据框,其中包含丢失的数据(NA)。我想找到只有一个非缺失值的列,然后用该值填充这些列。例如,如果我的原始数据集是这样的:

  df = data.frame(A=c(1,2,NA,NA,1), B=c(NA,NA,3,3,3), C=c(2,5,6,3,6), D = c(NA,1, NA,1,1))

   A  B C  D
1  1 NA 2 NA
2  2 NA 5  1
3 NA  3 6 NA
4 NA  3 3  1
5  1  3 6  1 

我想实现:

   A  B C  D
1  1  3 2  1
2  2  3 5  1
3 NA  3 6  1
4 NA  3 3  1
5  1  3 6  1 

我首先创建此函数是为了执行我想要的操作:(请告诉我您是否对此有更好的选择)

fill_NAs <- function(x){
  x %>% fill(., .direction = "up") %>%
        fill(., .direction = "down")
}

然后我尝试使用mutate_at或mutate_if函数,但是我无法使其正常工作。我的一些尝试如下:

1)

df= df %>% mutate_if ( ~ length(unique(na.omit(.)))==1, ~ fill_NAs(.))

我收到此错误:

  

mutate_impl(.data,点)中的错误:评估错误:不适用   “ fill_”方法应用于类“ c('double',   '数字')“

2)

df_PMM_imp = df_PMM_imp %>% mutate_at(.,names(select_if(.,length(unique(na.omit(.)))==1)), ~ fill_NAs(.))

我收到此错误:

  

tbl_if_vars(.tbl,.predicate,caller_env(),   .include_group_vars = TRUE):length(.p)== length(tibble_vars)为   不正确

通常来说,我似乎无法理解mutate_if或mutate_at的逻辑,我总是遇到这样的问题。所以我的问题是:

1)什么是实现我想要的正确语法? 2)为什么我在上面得到这些错误,我在做什么错了?

非常感谢。

3 个答案:

答案 0 :(得分:1)

您可以遍历各列,检查不是NA的唯一元素的长度,如果列中仅包含一个唯一元素,则替换列中的NA

df[] <- lapply(df, function(x) {
  y <- unique(na.omit(x))
  if(length(y) == 1) {
    x <- y
  } else x
})

结果

df
   A B C D
1  1 3 2 1
2  2 3 5 1
3 NA 3 6 1
4 NA 3 3 1
5  1 3 6 1

答案 1 :(得分:0)

你好,@ Elif CansuAkoğuz,

通过使用for()循环遍历数据框并检查每一列是否满足要求,您可以相当轻松地实现目标:

for (i in 1:ncol(df)) {
    if (any(is.na(unique(df[i]))) == TRUE & nrow(unique(df[i])) == 2) {
        ...
    }
}

使用语句any(is.na(unique(df[i]))),您可以检查列中是否有NA;使用nrow(unique(df[i])) == 2,您可以检查列中是否仅包含两个唯一值。因此,如果一列同时满足这两个语句,您就会知道它由2个值组成,其中一个在NA中。

接下来,您要用非NA的值替换列中的所有值。为此,您可以使用na.omit()抛出NA值,然后重复剩余的值,无论数据帧有多长。 一个问题是,它将返回列表格式,因此您必须使用unlist()函数来解决此问题。

整个循环最终看起来像这样:

for (i in 1:ncol(df)) {
    if (any(is.na(unique(df[i]))) == TRUE & nrow(unique(df[i])) == 2) {
        df[i] <- unlist(rep(na.omit(unique(df[i])), nrow(df)))
    }
}

祝你好运!

答案 2 :(得分:0)

一种dplyr方式:

library(dplyr)

df %>% 
  mutate_all(~ case_when(
    n_distinct(.[na.omit(.)]) == 1 ~ first(na.omit(.)),
    TRUE ~ .
    )
  )

输出:

   A B C D
1  1 3 2 1
2  2 3 5 1
3 NA 3 6 1
4 NA 3 3 1
5  1 3 6 1