Reputation: 333
I wonder how I can access all the columns with a particular name in nested lists. Below there is a reproducible example. How can I call all the "mean" columns and collate all in a single data.frame where the data.frame as two other columns which specify associated classes and Output1/Output2 (Example 1). Example 2 is a little more complicated where the nested "mean" list is a data.frame. I need to access both "ts" and "value" columns. In other words, I need to know the ts corresponding to each value (in addition to classes and Output1/Output2).
Example 1
classes <- c("F", "G", "M", "O")
classes <- structure(unique(classes), names = unique(classes))
S1 = data.frame(X1 = rnorm(100), X2 = rnorm(100), X3 = rnorm(100), X4 = rep(classes, 25))
S2 = data.frame(X1 = rnorm(100), X2 = rnorm(100), X3 = rnorm(100), X4 = rep(classes, 25))
P <- lapply(classes, function(c){
Output1 <- list ("model" = lm(X3~ X1+X2, data = S1),"mean" = apply(S1[S1$X4 == c, 1:3], 2, mean), "sum" = apply(S1[S1$X4 == c, 1:3], 2, sum))
Output2 <- list ("model" = lm(X3~ X1+X2, data = S2), "mean" = apply(S2[S2$X4 == c, 1:3], 2, mean), "sum" = apply(S2[S2$X4 == c, 1:3], 2, sum))
output <- list ("Output1" = Output1, "Output2" = Output2)
return(output)
})
Example 2
classes <- c("F", "G", "M", "O")
classes <- structure(unique(classes), names = unique(classes))
S1 = data.frame( X1 = rnorm(100), X2 = rnorm(100), X3 = rnorm(100), X4 = rep(classes, 25), ts = seq(from = ISOdate(1910,1,1), by = "30 min", length.out = 100 ))
S2 = data.frame( X1 = rnorm(100), X2 = rnorm(100), X3 = rnorm(100), X4 = rep(classes, 25),ts = seq(from = ISOdate(1910,1,1), by = "30 min", length.out = 100 ))
P <- lapply(classes, function(c){
Output1 <- list ("model" = lm(X3~ X1+X2, data = S1),"mean" = data.frame(ts = S1[S1$X4 == c, "ts"],
value = S1[S1$X4 == c, "X1"]) ,
"sum" = apply(S1[S1$X4 == c, 1:3], 2, sum))
Output2 <- list ("model" = lm(X3~ X1+X2, data = S2),
"mean" = data.frame(ts = S2[S2$X4 == c, "ts"],
value = S2[S2$X4 == c, "X1"]),
"sum" = apply(S2[S2$X4 == c, 1:3], 2, sum))
output <- list ("Output1" = Output1, "Output2" = Output2)
return(output)
})
Upvotes: 1
Views: 305
Reputation: 388982
We can get "mean" columns from P
using rvest
's pluck
and bind them together with map_df
.
purrr::map_df(P, ~rvest::pluck(.x, "mean"), .id = "Class")
# A tibble: 12 x 3
# Class Output1 Output2
# <chr> <dbl> <dbl>
# 1 F 0.0315 -0.0946
# 2 F 0.0935 0.219
# 3 F 0.155 0.172
# 4 G 0.123 0.182
# 5 G -0.114 -0.128
# 6 G -0.0654 -0.0990
# 7 M 0.111 0.0794
# 8 M -0.176 0.405
# 9 M 0.265 -0.0747
#10 O 0.0207 -0.250
#11 O -0.0407 0.0117
#12 O -0.162 -0.195
In base R, you can do :
temp <- lapply(P, function(x) sapply(x, `[[`, "mean"))
do.call(rbind, Map(cbind.data.frame, temp, Class = names(temp)))
EDIT
For the dataframe example, we can use bind_rows
after pluck
.
map_df(P, ~rvest::pluck(.x, "mean") %>% bind_rows(.id= "output"), .id = "Class")
Upvotes: 4