user2907393
user2907393

Reputation: 3

Extract results from list of list and maintain column indicators

I've been trying to extract data from a list of summaries and keep the columns indicators.

Here is an example of the data

data = data.frame( Var1 = c("Esp1"), Var2 = c("Tra1", "Tra2", "Tra3"))
data$New[[1]] <- c(list(data.frame( P.value =runif(1, 0.03, 0.08) , DF =runif(1, 1, 4) , ChisQ =runif(1, 0.03, 0.08) )),list(data.frame(factor = c("z"), value= sample(100,1))) , list(data.frame(factor = c(1:4), value= sample(100,4))) , list(data.frame( Group = c("A"), row.names =c("Control", "X1", "X2", "X3", "X4"), Value =sample(100, size=5, replace = TRUE))))
data$New[[2]] <- c(list(data.frame( P.value =runif(1, 0.03, 0.08) , DF =runif(1, 1, 4) , ChisQ =runif(1, 0.03, 0.08) )),list(data.frame(factor = c("z"), value= sample(100,1))) , list(data.frame(factor = c(1:4), value= sample(100,4))) , list(data.frame( Group = c("A"), row.names =c("Control", "X1", "X2", "X3", "X4"), Value =sample(100, size=5, replace = TRUE))))
data$New[[3]] <- c(list(data.frame( P.value =runif(1, 0.03, 0.08) , DF =runif(1, 1, 4) , ChisQ =runif(1, 0.03, 0.08) )),list(data.frame(factor = c("z"), value= sample(100,1))) , list(data.frame(factor = c(1:4), value= sample(100,4))) , list(data.frame( Group = c("A"), row.names =c("Control", "X1", "X2", "X3", "X4"), Value =sample(100, size=5, replace = TRUE))))
names(data$New[[1]]) <- c("Statistics","xx1","xx2",  "groups")
names(data$New[[2]]) <- c("Statistics","xx1","xx2",  "groups")
names(data$New[[3]]) <- c("Statistics","xx1","xx2",  "groups")

I'd like to extract from each list of results, only the groups ( 5 rows) and statistics (1 row) tabs and place them on a table along with the respective value of column Var 1 and Var2. In the tab groups tabs, the row.names indicates the treatment used for the analysis .

I tried to use broom::tidy ( it worked for other list of results), but failed for this list distribution

So far, I've been able to create the table from the extracted groups and its related rowname, but cannot get to set the correct Var1 and Var2 values properly.

data.1 <- lapply(data[[3]], function(x) x$groups)
data.2 <- lapply(data.1, function(x) { x$Treatment <-rownames(x);return(x)})
data.group<- do.call(rbind.data.frame, data.2)
rownames(data.group) <- 1:nrow(data.group)

This is how far I've got

> data.group
   Group Value Treatment
1      A    24   Control
2      A    96        X1
3      A    76        X2
4      A    26        X3
5      A    10        X4
6      A    58   Control
7      A    33        X1
8      A    30        X2
9      A    54        X3
10     A    48        X4
11     A    66   Control
12     A    80        X1
13     A    97        X2
14     A    86        X3
15     A    86        X4

This lines doesn't work, cannot get lapply to read the columns Var1 and Var2

data.2.1 <- lapply(data.2, function(x) { x$Var1 <-unlist(data$Var1[[(x)]])  ;return(x)})
data.2.2 <- lapply(data.2, function(x) { x$Var2 <-data[[2]][[x]] ;return(x)})

This is how I'd like the table output to be

    > data.group
       Var1 Var2 Treatment Value Group            P.value                 Df
    1  Esp1 Tra1   Control    70     A 0.0730726366001181 0.0566315333195962
    2  Esp1 Tra1        X1    27     A                                      
    3  Esp1 Tra1        X2     3     A                                      
    4  Esp1 Tra1        X3    16     A                                      
    5  Esp1 Tra1        X4    58     A                                      
    6  Esp1 Tra2   Control     2     A 0.0669188804645091  0.043313137262594
    7  Esp1 Tra2        X1    58     A                                      
    8  Esp1 Tra2        X2    87     A                                      
    9  Esp1 Tra2        X3    12     A                                      
    10 Esp1 Tra2        X4    23     A                                      
    11 Esp1 Tra3   Control    58     A 0.0698359214654192 0.0380288420431316
    12 Esp1 Tra3        X1    80     A                                      
    13 Esp1 Tra3        X2    44     A                                      
    14 Esp1 Tra3        X3   100     A                                      
    15 Esp1 Tra3        X4    78     A                                      
                    ChisQ
    1  0.0551552523346618
    2                    
    3                    
    4                    
    5                    
    6  0.0415172106772661
    7                    
    8                    
    9                    
    10                   
    11 0.0434505424182862
    12                   
    13                   
    14                   
    15                   
    >  

Thanx for the replies !!

Upvotes: 0

Views: 79

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 389155

As Statistics and groups are dataframes that contain unrelated information than one another I would suggest you keep them in a list and select only the ones which are of interest.

data$New <- lapply(data$New,function(x)
                   list(Statistics = x$Statistics, groups = x$groups))
data$New

#[[1]]
#[[1]]$Statistics
#  P.value   DF  ChisQ
#1  0.0747 2.22 0.0345

#[[1]]$groups
#        Group Value
#Control     A    98
#X1          A    76
#X2          A    71
#X3          A    62
#X4          A    25


#[[2]]
#[[2]]$Statistics
#  P.value   DF  ChisQ
#1   0.074 3.71 0.0781

#[[2]]$groups
#        Group Value
#Control     A    31
#X1          A    92
#...
#....

For the updated expected output we can do

list_df <- lapply(data$New,function(x) data.frame(Control = rownames(x$groups), 
  Value = x$groups$Value, Group = x$groups$Group, P.value = x$Statistics$P.value, 
  DF = x$Statistics$DF, ChisQ = x$Statistics$ChisQ))

new_df <- data[rep(seq_len(nrow(data)), sapply(list_df, nrow)), ]
new_df$New <- NULL
cbind(new_df, do.call(rbind, list_df))

Or similar but using tidyverse

data$New <- purrr::map(data$New,function(x) data.frame(Control = rownames(x$groups),
   Value = x$groups$Value, Group = x$groups$Group, P.value = x$Statistics$P.value, 
    DF = x$Statistics$DF, ChisQ = x$Statistics$ChisQ))

data %>% tidyr::unnest(New)

Upvotes: 0

akrun
akrun

Reputation: 887531

We can use map from purrr

library(purrr)
library(dplyr)
data <- data %>%
     mutate(New = map(New, ~ list(Statistics = .x$Statistics, groups = .x$groups)))



data$New
#[[1]]
#[[1]]$Statistics
#     P.value       DF      ChisQ
#1 0.05901864 2.223526 0.07536408

#[[1]]$groups
#        Group Value
#Control     A    62
#X1          A    49
#X2          A    69
#X3          A    15
#X4          A    88


#[[2]]
#[[2]]$Statistics
#     P.value       DF      ChisQ
#1 0.06802287 1.506049 0.06263245

#[[2]]$groups
#        Group Value
# ...

Upvotes: 0

Related Questions