I have a list of dataframes. There are two types of dataframes, one listing names and ages, the other listing tests and grades (as in the 'combined list' below).
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)
I would like to subset the list into a dataframe consisting of only the names and the ages, so it would look something like this:
name age
1 Alice 23
2 Bob 41
3 Claire 50
4 David 32
I found the Keep function of the Purrr package, which should be able to filter the list based on a condition, but I haven't found a way to make it work. This is what I've tried so far:
library(purrr)
purrr:keep(function(x) filter(!name=NULL))
How can I make this work? Are there other solutions?
We create the logical condition to Filter
the elements of the list
where it returns a single TRUE. It can be done by wrapping with all
after creating a logical vector with %in%
ie subsetting only those elements having both 'name', and 'age' as column names. Then, we bind the list
elements to a single data.frame with bind_rows
library(dplyr)
library(purrr)
keep(combined_list, ~ all(c("name", 'age') %in% names(.x))) %>%
bind_rows
-output
# name age
#1 Alice 23
#2 Bob 41
#3 Claire 50
#4 David 32
Or another option is to bind all the datasets together, then select
only the relevant columns and remove the NA
rows
bind_rows(combined_list) %>%
select(name, age) %>%
na.omit
In base R
, we can use Filter
with rbind
inside do.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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.