【问题标题】:tidyverse - filtering within a nested column/list based on number of NA's per rowtidyverse - 根据每行 NA 的数量在嵌套列/列表中进行过滤
【发布时间】:2020-06-01 21:10:14
【问题描述】:

尝试在此处扩展我自己的工作流程(从列):[1] tidyverse - delete a column within a nested column/list 以在嵌套列/列表中进行过滤,我发现了这个潜在的解决方案:[2] Use filter() (and other dplyr functions) inside nested data frames with map()

我的问题是我想过滤那些不完全不适用的行的每个“嵌套”(即,我想保留任何至少具有一个非缺失值的行

但是,[2] 中的简单解决方案对我不起作用,可能是因为我想过滤每行 NA 的总和,这可能涉及过滤器中的另一个映射函数。

(注意:我在 tidyverse 中使用 dplyr 的当前 github 版本,它提供了一些新的实验功能,例如 condense - 我在下面使用,但我认为这与我的问题/问题无关)。

我有以下数据:

数据:

library(tidyverse)
library(corrr)

dat <- data.frame(grp = rep(1:4, each = 25),
                  Q1 = sample(c(1:5, NA), 100, replace = TRUE),
                  Q2 = sample(c(1:5, NA), 100, replace = TRUE),
                  Q3 = sample(c(1:5, NA), 100, replace = TRUE),
                  Q4 = sample(c(1:5, NA), 100, replace = TRUE),
                  Q5 = sample(c(NA), 100, replace = TRUE),
                  Q6 = sample(c(1:5, NA), 100, replace = TRUE))

我现在计算每组 Q1 到 Q6 的相关性并删除 rowname 列。

cor_dat <- dat %>%
  group_by(grp) %>%
  condense(cor = correlate(cur_data()) %>%
         select(-rowname)) %>%
  ungroup()

但是将此行添加到我的管道不起作用:

cor_dat <- cor_dat %>%
  mutate(cor = map(cor, ~ filter(., sum(is.na(.)) != ncol(.))))

我也试过了,但这也不起作用:

cor_dat <- cor_dat %>%
      mutate(cor = map(cor, ~ filter(., !all(is.na(.)))))

我的数据中的预期结果是每个嵌套中的第五行被过滤掉。

【问题讨论】:

  • 确实,相应地编辑了我的帖子
  • 当然。只是忘记了从另一个线程复制过来。相应地编辑了我的帖子。

标签: r nested tidyverse


【解决方案1】:

这里,我们可以使用filter_all

library(dplyr)
library(purrr)
cor_dat <- cor_dat %>% 
               mutate(cor = map(cor, ~ .x %>% 
                              filter_all(any_vars(!is.na(.)))))
cor_dat
# A tibble: 4 x 2
#    grp cor             
#  <int> <list>          
#1     1 <tibble [5 × 6]>
#2     2 <tibble [5 × 6]>
#3     3 <tibble [5 × 6]>
#4     4 <tibble [5 × 6]>

cor_dat$cor[[1]]
# A tibble: 5 x 6
#       Q1      Q2      Q3      Q4    Q5      Q6
#    <dbl>   <dbl>   <dbl>   <dbl> <dbl>   <dbl>
#1 NA      -0.226   0.288  -0.0536    NA  0.581 
#2 -0.226  NA      -0.382   0.212     NA  0.0274
#3  0.288  -0.382  NA      -0.0772    NA -0.153 
#4 -0.0536  0.212  -0.0772 NA         NA  0.0831
#5  0.581   0.0274 -0.153   0.0831    NA NA     

或者如果我们需要使用filter,那么使用rowSums创建逻辑

cor_dat %>%
       mutate(cor = map(cor, ~ .x %>%
                                  filter(rowSums(is.na(.)) < ncol(.))))

数据

cor_dat <- dat %>%
   group_by(grp) %>%
   condense(cor = correlate(cur_data()) %>% 
                 select(-rowname)) %>% 
   ungroup 

【讨论】:

  • 谢谢。我更喜欢您的第二个解决方案,因为 filter_all 已在 dplyr 1.0 中退休,而我还没有弄清楚如何使用新的 across 函数。
  • @deschen 你是对的。文档filter_at(mtcars, vars(starts_with("d")), any_vars((. %% 2) == 0))# # -&gt; filter(mtcars, across(starts_with("d"), ~ (.x %% 2) == 0))all_vars 存在一些不一致之处
  • @deschen 另外,还有一个问题。 github.com/tidyverse/dplyr/issues/4770我认为现在使用这些功能还为时过早,因为它仍处于开发阶段
猜你喜欢
  • 2023-02-11
  • 2017-02-08
  • 1970-01-01
  • 2017-07-09
  • 1970-01-01
  • 2021-01-14
  • 2021-12-18
  • 2015-03-28
  • 1970-01-01
相关资源
最近更新 更多