#r #dataframe #purrr #na
Вопрос:
У меня есть большой df
фрейм данных в R со многими столбцами, многими NAs, но ни один столбец не является полностью NA. Меня интересует конкретный список col_list
этих столбцов. Мне нужен образец фрейма данных, чтобы каждый столбец был представлен хотя бы один раз.
Моя мысль состояла в том, чтобы «перебрать» список map_dfr
столбцов, отфильтровав df
их там, где каждый столбец не является NA, а затем выбрать оттуда одну строку, как показано ниже.
library(tidyverse)
col_list %>%
map_dfr(function(name){
df %>%
filter(!is.na(name)) %>%
sample_n(1)
}) %>%
select(all_of(col_list))
К сожалению, некоторые столбцы в результате все еще оказываются пустыми. Судя по всему, те несколько столбцов, которые продолжают оставаться пустыми, имеют объем памяти выше среднего для кадра данных, но я знаю, что они не совсем пустые.
Я не могу поделиться своим набором данных и не могу придумать, как воспроизвести его на меньшем наборе данных, поэтому, к сожалению, я не могу создать reprex.
В чем может быть пробел в моей логике выше, и как его можно улучшить, чтобы не было столбцов во всех NA?
Изменить: Я принял первое решение ниже. Я также решил эту проблему с помощью лучшего выбора переменных env, поэтому я публикую здесь для потомков.
library(tidyverse)
col_list %>%
map_dfr(function(name){
df %>%
filter(!is.na(.data[[name]])) %>%
sample_n(1)
}) %>%
select(all_of(col_list))
Ответ №1:
Вот воспроизводимый пример (основанный на моем лучшем понимании вашего вопроса):
library(tidyverse)
df <- tibble(
x = c('hello', 'yes', 'no', NA),
y = c(NA, NA, NA, 'hi'),
z = c(1, 2, 3, 4)
)
col_list <- names(df)
col_list %>%
map_dfr(function(name){
df %>%
filter(!is.na(name)) %>%
sample_n(1)
}) %>%
select(all_of(col_list))
В этом сценарии filter()
функция ищет столбец с именем name
, которого (вероятно) не существует. Вы могли бы завернуться name
, !!sym()
и это должно сработать.
col_list %>%
map_dfr(function(name){
df %>%
filter(!is.na(!!sym(name))) %>%
sample_n(1)
}) %>%
select(all_of(col_list))
Комментарии:
1. Спасибо. Я также обнаружил, что замена
name
на.data[[name]]
исправляет это с точки зрения аккуратной оценки. Мне придется узнать об этом побольше.