Nile
Nile

Reputation: 333

Access all the columns with a particular name in nested lists in R

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

Answers (1)

Ronak Shah
Ronak Shah

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

Related Questions