У меня есть около 30 фреймов данных с разным количеством образцов, но с одинаковыми столбцами метаданных. Например, столбцы Sample ID,Date of collection,Place of collection,Days since sample collection и это лишь некоторые из них.
Я хочу обобщить их по критериям «Место сбора» и «Дни с момента сбора проб». Для этого я использую функцию ниже –
check_summary_df <- function(x) {
summarized_data <- x %>% group_by(place_of_collection, day) %>% summarize(count = n())
summarized_data$df_name <- deparse(substitute(x)) # adding this as a column so I can track the df_name
return(summarized_data)
}
И он предоставляет мне фрейм данных с необходимой сводкой. Мои имена df нестандартны, поэтому я поместил их в список, используя input_df_list <- c('df1','collected_by_x','collected_by_y'), и теперь хочу выполнить функцию по списку. Я попробовал простой цикл for -
for (i in 1:length(input_df_list)) { check_summary_df(input_df_list[i])}
И получил следующую ошибку:
Error in UseMethod("group_by") :
no applicable method for 'group_by' applied to an object of class "character"
Судя по тому, что я вижу, input_df_list[i] цикла распознает ввод как символьную строку, а не как фрейм данных. Как я могу изменить это поведение? Или есть ли другой способ перебрать список кадров данных?





Идиоматический способ сделать это в R — создать список фреймов данных, а не список имен, а затем перебрать его. Поскольку у вас уже есть input_df_list, вектор символов имен, вы можете сделать это с помощью get(). Вот пример:
# Vector of names
input_df_list <- c("iris", "mtcars", "cars")
# Create a list of data frames
df_list <- lapply(input_df_list, \(nm) get(nm)) |>
setNames(input_df_list)
# Simple function we can apply to all data frames
check_summary_df <- function(dat) {
names(dat)
}
# Apply function to each data frame
lapply(df_list, check_summary_df)
# $iris
# [1] "Sepal.Length" "Sepal.Width" "Petal.Length" "Petal.Width" "Species"
# $mtcars
# [1] "mpg" "cyl" "disp" "hp" "drat" "wt" "qsec" "vs" "am" "gear" "carb"
# $cars
# [1] "speed" "dist"
Вы также можете добавить x <- get(x) в верхнюю строку своей функции, но вы обнаружите, что ваш код R будет более читаемым, если вы работаете со списками фреймов данных.
Эй! Добавление x <- get(x вроде работает, но имя фрейма данных не отображается в списке тибблов. Команда df_list сработала, однако что именно делает \(nm)...*? «получить» фрейм данных и назвать его согласно input_df_list?
@KarthikNair \(nm) — это сокращение от function(nm). Вы можете заменить эту строку на df_list <- setNames(mget(input_df_list), input_df_list), чтобы это было легче понять. Причина, по которой вы получаете именованный список в конце, заключается в том, что setNames() — либо установите имена входного списка, и вы получите именованный список, либо установите выходной список.
Вы проверили, действительно ли этот элемент является символом, а не фреймом данных? Если да, то почему это персонаж? Вы уверены, что все элементы являются фреймами данных? Вы правильно прочитали фреймы данных в списке? Проверьте свои данные.