У вас есть вложенный список (датчики) списков (измерений) списков (фреймов данных), где каждый из них хочет lapply
.
Я уверен, что есть также решение rapply
Возможно, хотя.
Поскольку я ответил на один из ваших предыдущих вопросов Я предполагаю, что вы хотите выполнить агрегацию по каждому датчику.
Вы можете уточнить lapply
подход, свернув некоторые из подсписков. Поэтому вы могли бы рассмотреть, например, эти три решения.
Решение 1
Получение структуры списка, аналогичной исходной, всего лишь дней aggregate
d для каждого года.
res1 <- lapply(dat, function(se)
lapply(se, function(m)
lapply(m, function(d)
aggregate(swc ~ date, d, sum))))
Структура результирующего списка
str(res1, 3)
# List of 3
# $ SE104:List of 3
# ..$ d20:List of 11
# .. ..$ 2009:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2010:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2011:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2012:'data.frame': 366 obs. of 2 variables:
# .. ..$ 2013:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2014:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2015:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2016:'data.frame': 366 obs. of 2 variables:
# .. ..$ 2017:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2018:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2019:'data.frame': 365 obs. of 2 variables:
# ..$ d50:List of 11
# .. ..$ 2009:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2010:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2011:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2012:'data.frame': 366 obs. of 2 variables:
# .. ..$ 2013:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2014:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2015:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2016:'data.frame': 366 obs. of 2 variables:
# .. ..$ 2017:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2018:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2019:'data.frame': 365 obs. of 2 variables:
# ..$ d5 :List of 11
# .. ..$ 2009:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2010:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2011:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2012:'data.frame': 366 obs. of 2 variables:
# .. ..$ 2013:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2014:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2015:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2016:'data.frame': 366 obs. of 2 variables:
# .. ..$ 2017:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2018:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2019:'data.frame': 365 obs. of 2 variables:
# $ SE105:List of 3
# ..$ d20:List of 11
# .. ..$ 2009:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2010:'data.frame': 365 obs. of 2 variables:
# .. ..$ 2011:'data.frame': 365 obs. of 2 variables:
# [...]
Пример кадра данных результата
head(res1$SE104$d20$`2009`)
# date swc
# 1 2009-01-01 7.642943
# 2 2009-01-02 2.251837
# 3 2009-01-03 -2.579394
# 4 2009-01-04 5.265464
# 5 2009-01-05 -2.891591
# 6 2009-01-06 -12.054497
Решение 1 (расширенное)
Усовершенствованная версия решения 1, которая обходит ошибки от aggregate
при ncol(x) == 0
с использованием tryCatch()
.
dat2 <- dat ## copy of dat
## intentionally make one data frame of nrow == 0
dat2$SE104$d20$`2009` <- data.frame(date=as.Date(character()),
swc=double())
res1.enh <- lapply(dat2, function(se)
lapply(se, function(m)
setNames(lapply(1:length(m), function(d)
tryCatch(aggregate(swc ~ date, m[[d]], function(x) sum(x, na.rm=TRUE)),
error=function(e) {
## mimicks aggregate result with NA column for swc
y <- as.numeric(names(m)[d])
cbind.data.frame(
date=as.Date(as.character(seq(ISOdate(y, 1, 1, 0),
ISOdate(y, 12, 31, 0), by="day"))),
swc=NA)
})), names(m))))
Пример результата, когда ncol == 0
head(res1.enh$SE104$d20$`2009`)
# date swc
# 1 2009-01-01 NA
# 2 2009-01-02 NA
# 3 2009-01-03 NA
# 4 2009-01-04 NA
# 5 2009-01-05 NA
# 6 2009-01-06 NA
** Нормальный результат *
head(res1.enh$SE104$d20$`2010`)
# date swc
# 1 2010-01-01 -1.001692
# 2 2010-01-02 -2.531776
# 3 2010-01-03 6.036390
# 4 2010-01-04 -5.470039
# 5 2010-01-05 -1.659984
# 6 2010-01-06 -8.495954
Решение 2
Как и решение 1, когда годы свернулись.
res2 <- lapply(dat, function(se)
lapply(se, function(m)
aggregate(swc ~ date, do.call(rbind, m), sum)))
Структура полученного результата список
str(res2)
# List of 3
# $ SE104:List of 3
# ..$ d20:'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] 7.64 2.25 -2.58 5.27 -2.89 ...
# ..$ d50:'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] -7.658 -10.792 2.617 0.811 4.529 ...
# ..$ d5 :'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] 2.52 2.01 7.26 5.33 -5.01 ...
# $ SE105:List of 3
# ..$ d20:'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] 5.88 -5.2 -7.11 2.57 2.29 ...
# ..$ d50:'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] -10.09 -6.48 4.57 -7.04 -7.81 ...
# ..$ d5 :'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] -0.329 -4.42 -1.826 -7.249 1.083 ...
# $ SE106:List of 3
# ..$ d20:'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] 4.905 -4.207 2.128 0.121 -2.668 ...
# ..$ d50:'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] 4.092 -4.983 -7.234 -6.362 -0.135 ...
# ..$ d5 :'data.frame': 4017 obs. of 2 variables:
# .. ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# .. ..$ swc : num [1:4017] 2.13 4.26 10.59 0.56 2.36 ...
Пример кадра данных результата
head(res2$SE104$d20)
# date swc
# 1 2009-01-01 7.642943
# 2 2009-01-02 2.251837
# 3 2009-01-03 -2.579394
# 4 2009-01-04 5.265464
# 5 2009-01-05 -2.891591
# 6 2009-01-06 -12.054497
Решение 3
Вид широкого формата решения 2.
res3 <- lapply(dat, function(se) {
tmp <- lapply(se, function(m) do.call(data.frame, aggregate(swc ~ date, do.call(rbind, m), sum)))
data.frame(date=el(tmp)[["date"]], setNames(mapply(`[`, tmp, 2), names(se)))
})
Структура результирующего списка
str(res3)
# List of 3
# $ SE104:'data.frame': 4017 obs. of 4 variables:
# ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# ..$ d20 : num [1:4017] 7.64 2.25 -2.58 5.27 -2.89 ...
# ..$ d50 : num [1:4017] -7.658 -10.792 2.617 0.811 4.529 ...
# ..$ d5 : num [1:4017] 2.52 2.01 7.26 5.33 -5.01 ...
# $ SE105:'data.frame': 4017 obs. of 4 variables:
# ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# ..$ d20 : num [1:4017] 5.88 -5.2 -7.11 2.57 2.29 ...
# ..$ d50 : num [1:4017] -10.09 -6.48 4.57 -7.04 -7.81 ...
# ..$ d5 : num [1:4017] -0.329 -4.42 -1.826 -7.249 1.083 ...
# $ SE106:'data.frame': 4017 obs. of 4 variables:
# ..$ date: Date[1:4017], format: "2009-01-01" "2009-01-02" "2009-01-03" ...
# ..$ d20 : num [1:4017] 4.905 -4.207 2.128 0.121 -2.668 ...
# ..$ d50 : num [1:4017] 4.092 -4.983 -7.234 -6.362 -0.135 ...
# ..$ d5 : num [1:4017] 2.13 4.26 10.59 0.56 2.36 ...
Заголовки трех фреймов данных в результирующем списке
lapply(res3, head)
# $SE104
# date d20 d50 d5
# 1 2009-01-01 7.642943 -7.6576879 2.520563
# 2 2009-01-02 2.251837 -10.7916635 2.012231
# 3 2009-01-03 -2.579394 2.6173333 7.260413
# 4 2009-01-04 5.265464 0.8107366 5.327772
# 5 2009-01-05 -2.891591 4.5289522 -5.014450
# 6 2009-01-06 -12.054497 -5.9274899 1.441439
#
# $SE105
# date d20 d50 d5
# 1 2009-01-01 5.880239 -10.093960 -0.3288049
# 2 2009-01-02 -5.196587 -6.478163 -4.4196227
# 3 2009-01-03 -7.114667 4.568871 -1.8259147
# 4 2009-01-04 2.565384 -7.039717 -7.2492291
# 5 2009-01-05 2.289701 -7.808063 1.0832635
# 6 2009-01-06 -1.674715 4.360558 2.2994494
#
# $SE106
# date d20 d50 d5
# 1 2009-01-01 4.9053760 4.0917553 2.132417
# 2 2009-01-02 -4.2074579 -4.9825570 4.256667
# 3 2009-01-03 2.1284944 -7.2339473 10.588332
# 4 2009-01-04 0.1208879 -6.3617098 0.560269
# 5 2009-01-05 -2.6676826 -0.1350602 2.364006
# 6 2009-01-06 -3.0595029 7.9359285 6.903543
Данные игрушки:
dat <- setNames(replicate(3, setNames(replicate(3, setNames(lapply(2009:2019, function(y) {
d <- expand.grid(date=as.Date(as.character(seq(ISOdate(y, 1, 1, 0), ISOdate(y, 12, 31, 0), by="day"))),
hour=1:24)
d$swc <- rnorm(nrow(d))
d[order(d$date), -2]
}), 2009:2019), simplify=F), c("d20", "d50", "d5")), simplify=F), c("SE104", "SE105", "SE106"))