Как выбрать столбцы только с NA и уникальным значением и заполнить NA этим значением? - PullRequest
0 голосов
/ 20 января 2019

У меня есть фрейм данных, некоторые столбцы которого имеют только уникальное значение или NA.Я хочу выбрать эти столбцы и заполнить NA в этих столбцах уникальной непропущенной переменной в столбце.

Вот фиктивные данные:

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

Я хочу получить:

#df
#   A B   C
#1  1 2   3
#2  1 NA  3
#3  1 5   3
#4  1 2   3
#5  1 5   3

До сих пор я пытался:

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

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

Оба выдавали следующую ошибку:

Ошибка в зонде (.x, .p): length (.p) == length (.x) не ИСТИНА

Может кто-нибудь сказать, какой правильный синтаксис для достижения того, что я хочу?

Ответы [ 2 ]

0 голосов
/ 20 января 2019

Мы могли бы проверить условие в mutate_if и, если оно удовлетворено, использовать первое не-NA значение для всего столбца

library(tidyverse)

df %>%
  mutate_if(~n_distinct(.[!is.na(.)]) == 1, funs(.[!is.na(.)][1]))


#  A  B C
#1 1  2 3
#2 1 NA 3
#3 1  5 3
#4 1  2 3
#5 1  5 3

, которое также может быть записано в соответствии с предложением @ RHertel

df %>% mutate_if(~n_distinct(.[na.omit(.)]) == 1, funs(na.omit(.)[1]))

Чтобы было яснее, мы могли бы создавать функции и использовать их соответственно

only_one_unique <- function(x) {
   n_distinct(x[!is.na(x)]) == 1
}

first_non_NA_value <- function(x) {
   x[!is.na(x)][1]
}

df %>%  mutate_if(only_one_unique, first_non_NA_value)

Мы могли бы хранить все в базе R, используя ту же логику

only_one_unique <- function(x) {
   length(unique(x[!is.na(x)])) == 1
}

first_non_NA_value <- function(x) {
   x[!is.na(x)][1]
}

df[] <- lapply(df, function(x) if (only_one_unique(x)) 
                                   first_non_NA_value(x) else x)
0 голосов
/ 20 января 2019

Возможно, я неправильно понял ваш вопрос, но разве это не просто вопрос fill?

df %>% fill(A, C)
#  A B C
#1 1 2 3
#2 1 4 3
#3 1 5 3
#4 1 2 3
#5 1 5 3

Чтобы заполнить все столбцы, а также чтобы убедиться, что столбцы, начинающиеся с NA, заполнены, мы можем заполнить значения в обоих направлениях (вверх и вниз):

df %>% fill(everything()) %>% fill(everything(), .direction = "down")

Обновление

Теперь, когда я понял ваш вопрос, мы можем использовать mutate_if с вашим условным выражением, равным replace значениям

df %>%
    mutate_if(
        function(x) length(unique(na.omit(x))) == 1,
        function(x) replace(x, is.na(x), unique(na.omit(x))))
#  A  B C
#1 1  2 3
#2 1 NA 3
#3 1  5 3
#4 1  2 3
#5 1  5 3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...