#r #dplyr #purrr
#r #dplyr #purrr
Вопрос:
У меня есть список больших фреймов данных, и я хочу подмножество каждого из них, сохраняя только определенные столбцы. Имена столбцов, которые я хочу, содержатся в векторах символов, уникальных для каждого фрейма данных.
Один из способов сделать это — использовать рабочий процесс со списком столбцов. Я бы создал фрейм данных со data
списком-столбцом, содержащим фреймы данных, и cols
списком-столбцом, содержащим символьные векторы.
Реальное применение этого будет включать список из 24 больших наборов данных в сочетании со списком из 24 уникальных символов vecotr. Вот минимальный пример этой структуры данных, чтобы проиллюстрировать проблему:
set.seed(2346)
df <- tibble(
col1 = sample(c(0,1), replace=T, size=10),
col2 = sample(c(0,1), replace=T, size=10),
col3 = sample(c(0,1), replace=T, size=10),
col4 = sample(c(0,1), replace=T, size=10)
)
cols <- c("col1", "col3")
df_list_col <- tibble(
data = list(df),
cols = list(cols)
)
df_list_col
имеет структуру списка-столбца, но только в одной строке.
Мое попытанное решение — создать третий столбец списка для хранения подмножества фрейма данных. Таким образом:
df_output <- df_list_col %>%
mutate(subset = select(.$data, !!.$cols))
Но это возвращает ошибку:
# Error: Problem with `mutate()` input `subset`.
# x `select()` doesn't handle lists.
# ℹ Input `subset` is `select(.$data, list(c("col1", "col3")))`.
Я также пытался использовать purrr::map
для применения функции:
df_output <- df_list_col %>%
mutate(subset = map(.$data, ~ select(.x, !!.$cols)))
Но это возвращает аналогичную ошибку. В обоих случаях select()
вектор имен столбцов отображается как список, а не как вектор. И я в тупике, как изменить это поведение.
Заранее спасибо за любую помощь!
Ответ №1:
Оба являются list
столбцами. Мы можем извлекать, вводя unlist
или извлекая с [[
помощью in select
dplyr::select(df_list_col$data[[1]], unlist(df_list_col$cols))
Или другой вариант с !!!
select(df_list_col$data[[1]], !!! df_list_col$cols)
Или с использованием tidyverse
синтаксиса
library(dplyr)
library(purrr)
df_list_col %>%
mutate(subset = map2(data, cols, ~ .x %>% select(all_of(.y))))
-вывод
# A tibble: 1 x 3
# data cols subset
# <list> <list> <list>
#1 <tibble [10 × 4]> <chr [2]> <tibble [10 × 2]>
Или с помощью pmap
df_list_col %>%
mutate(subset = pmap(cur_data(), ~ select(..1, all_of(..2 ))))
Комментарии:
1. Спасибо, как всегда, akrun, это отличные предложения. Я предпочитаю вариант с
mutate()
, потому что он концептуально наилучшим образом соответствует рабочему процессу со списком столбцов. Я увеличу это до реальной проблемы с данными и посмотрю, как это работает там.