首页 > 解决方案 > 如何使用 Purrr 从列表中过滤数据框?

问题描述

我有一个数据框列表。有两种类型的数据框,一种列出姓名和年龄,另一种列出测试和成绩(如下面的“组合列表”所示)。

df1 <- data.frame(name = c("Alice", "Bob"),
                 age = c(23, 41))
df2 <- data.frame(test = c("Geography", "Science"),
                  grade = c("A", "B"))
df3 <- data.frame(name = c("Claire", "David"),
                  age= c(50, 32))
df4 <- data.frame(test = c("Geography", "Science"),
                  grade = c("B", "B"))

combined_list <- c(df1,df2,df3,d4)

我想将列表子集化为仅包含名称和年龄的数据框,因此它看起来像这样:

   name age
1 Alice  23
2   Bob  41
3 Claire 50
4 David  32

我找到了 Purrr 包的 Keep 功能,它应该可以根据条件过滤列表,但我还没有找到让它工作的方法。这是我迄今为止尝试过的:

library(purrr)
purrr:keep(function(x) filter(!name=NULL))

我怎样才能使这项工作?还有其他解决方案吗?

标签: rtidyversepurrr

解决方案


我们为返回单个 TRUEFilter的元素创建逻辑条件。list它可以通过all在创建逻辑向量后包装来完成,%in%即仅将那些同时具有“名称”和“年龄”作为列名的元素设置子集。然后,我们将list元素绑定到单个 data.framebind_rows

library(dplyr)
library(purrr)
keep(combined_list, ~  all(c("name", 'age') %in% names(.x))) %>% 
     bind_rows

-输出

#     name age
#1  Alice  23
#2    Bob  41
#3 Claire  50
#4  David  32

或者另一种选择是将所有数据集绑定在一起,然后select只绑定相关列并删除NA

bind_rows(combined_list) %>% 
    select(name, age) %>% 
    na.omit

base R中,我们可以使用Filterwith rbindinsidedo.call

do.call(rbind, Filter(function(x) 
      all(c("name", "age") %in% names(x)), combined_list))
#    name age
#1  Alice  23
#2    Bob  41
#3 Claire  50
#4  David  32

数据

combined_list <- list(df1,df2,df3,df4)

推荐阅读