首页 > 解决方案 > 在 R 中,在数据框中采样足够多的行,没有一列是空的

问题描述

我在 R 中有一个很大的数据框df,有很多列,很多 NA,但没有一列完全是 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))

不幸的是,结果中的某些列仍然为空。从它的外观来看,不断出现空的少数列的数据帧的 NA 数量高于平均水平,但我知道它们并不完全是空的。

我无法共享我的数据集,我想不出如何在较小的数据集上重现它,所以很遗憾我无法生成一个代表。

我上面的逻辑中的差距可能是什么,以及如何改进以使所有列都没有 NA?

编辑:我已经接受了下面的第一个解决方案。我还通过更好的 env-variable selection解决了这个问题,所以我在这里发布以供后代使用。

library(tidyverse)

col_list %>% 
  map_dfr(function(name){
    df %>% 
      filter(!is.na(.data[[name]])) %>%
      sample_n(1)
  }) %>% 
  select(all_of(col_list))

标签: rdataframepurrrna

解决方案


Here is a reproducible example (based on my best understanding of your question):

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))

In this scenario, the filter() function is looking for the column named name which (probably) does not exist. You could wrap name in !!sym() and that should do the trick.

col_list %>% 
  map_dfr(function(name){
    df %>% 
      filter(!is.na(!!sym(name))) %>% 
      sample_n(1)
  }) %>% 
  select(all_of(col_list))

推荐阅读