У меня есть очень большой list(), который имеет +2000 элементов, где каждый элемент имеет два вектора (x и y) с разными размерами между элементами списка.
Пример:
new_list<-list(data.frame(x = c(1,2,3),
y = c(3,4,5)),
data.frame(x = c(3,2,2,2,3,8),
y = c(5,2,3,5,6,7)),
data.frame(x = c(3,2,2,1,1),
y = c(5,2,3,3,2)))
Я хотел бы усреднить только векторы x
в этом списке, чтобы получить что-то вроде этого:
df_mean<-data.frame(x=c(2,3.333,1.8))
Вы можете рассчитать colMeans
для каждого столбца, в котором есть x с sapply
, следующим образом:
data.frame(x = sapply(new_list, \(x) colMeans(x[grepl('x', names(x))])))
#> x
#> 1 2.000000
#> 2 3.333333
#> 3 1.800000
@nicola предложила такой вариант получше (спасибо!):
data.frame(x = sapply(new_list, \(x) mean(x$x)))
#> x
#> 1 2.000000
#> 2 3.333333
#> 3 1.800000
Created on 2023-02-06 with reprex v2.0.2
Использование map
library(purrr)
library(dplyr)
map_dfr(new_list, ~ .x %>%
summarise(x = mean(x)))
x
1 2.000000
2 3.333333
3 1.800000
один квест: в map_dfr(new_list, ~ .x
"x" это функция или переменная x из списка?
@ wesleysc352 это лямбда-функция, синтаксис function(x) x
в tidyverse. ~
относится к function(.x)
Вы также можете enframe
список и сделать mean
по группам:
library(dplyr) #1.1.0 or higher
library(tibble)
enframe(new_list) %>%
unnest(value) %>%
summarise(x = mean(x), .by = name)
# name x
#1 1 2
#2 2 3.33
#3 3 1.8
Хороший ответ Квинтена. Обычно я предпочитаю следовать принципу KISS. Вот формат, который я считаю синтаксически более простым:
len <- length(new_list)
sapply(1:len, function(z) mean(new_list[[z]][[1]]))
[1] 2.000000 3.333333 1.800000
В этом относительно простом случае я бы предпочел более краткое решение, предложенное @quinten. Однако, если вам нужно рассчитать дополнительную статистику по вложенным фреймам данных, вы можете рассмотреть что-то вроде этого:
library(tidyverse)
tibble(data = new_list) |>
rowwise() |>
summarise(
x = mean(data$x)
)
#> # A tibble: 3 × 1
#> x
#> <dbl>
#> 1 2
#> 2 3.33
#> 3 1.8
или альтернативно
tibble(data = new_list) |>
rowwise() |>
summarise(
data |>
summarise(x = mean(x))
)
#> # A tibble: 3 × 1
#> x
#> <dbl>
#> 1 2
#> 2 3.33
#> 3 1.8
Использование data.table
-х rbindlist
:
data.table::rbindlist(new_list, idcol = TRUE)[, .(x = mean(x)), .id][, 2]
#> x
#> 1: 2.000000
#> 2: 3.333333
#> 3: 1.800000
Почему бы не просто
\(x) mean(x$x)
?