Search code examples
rlistdataframet-test

Convert two lists to dataframe in R


I conducted t test on two data frames and stored results in two separate variables. They turned out to be lists. Now, I want to make a dataframe of t scores and p-values but I am not sure how to do that. I guess the lists are s3 class. The code.

AML_ttest <- apply(aml_df,1,t.test)
nrml_ttest <- apply(nrml_df,1,t.test)

Running AML_ttest[[9]] gives the following result.

One Sample t-test

data:  newX[, i]
t = 25.994, df = 25, p-value < 2.2e-16
alternative hypothesis: true mean is not equal to 0
95 percent confidence interval:
 6.612063 7.749997
sample estimates:
mean of x 
  7.18103 

How I can get the t and p-value from each list element? And make a new dataframe?

Thanks.

---UPDATE---

I tried the following code.

# AML
AML_ttest <- apply(aml_df,1,t.test)
AML_ttest = do.call(rbind,AML_ttest)
res_AML_ttest <- AML_ttest[,c("statistic","p.value")]

# Normal
nrml_ttest <- apply(nrml_df,1,t.test)
nrml_ttest = do.call(rbind,nrml_ttest)
res_nrml_ttest <- nrml_ttest[,c("statistic","p.value")]

# Make df
df_ttest <- data.frame(res_AML_ttest, res_nrml_ttest)
df_ttest

# Output
     statistic   p.value    statistic.1 p.value.1
1    56.71269 6.171562e-28    144.5161 1.569932e-52
2    75.79649 4.559861e-31    74.87025 5.317292e-42
3    17.68306 1.207297e-15    15.15478 1.891711e-17
4    108.4904 5.984139e-35    168.8557 4.993433e-55
5    152.8165 1.156183e-38    192.4672 3.959361e-57
6    63.21714 4.163004e-29    90.42468 5.112986e-45

Is this approach good? AM I good to go?


Solution

  • I'll test with this sample data:

    TT1 <- apply(mtcars[1:3], 2, t.test)
    

    We can peek at the structure of one of them to see what names to look for.

    str(TT1[[1]])
    # List of 10
    #  $ statistic  : Named num 18.9
    #   ..- attr(*, "names")= chr "t"
    #  $ parameter  : Named num 31
    #   ..- attr(*, "names")= chr "df"
    #  $ p.value    : num 1.53e-18
    #  $ conf.int   : num [1:2] 17.9 22.3
    #   ..- attr(*, "conf.level")= num 0.95
    #  $ estimate   : Named num 20.1
    #   ..- attr(*, "names")= chr "mean of x"
    #  $ null.value : Named num 0
    #   ..- attr(*, "names")= chr "mean"
    #  $ stderr     : num 1.07
    #  $ alternative: chr "two.sided"
    #  $ method     : chr "One Sample t-test"
    #  $ data.name  : chr "newX[, i]"
    #  - attr(*, "class")= chr "htest"
    

    This suggests we can use "statistic" and "p.value" for that. A direct approach:

    TT1[[1]][ c("statistic", "p.value") ]
    # $statistic
    #        t 
    # 18.85693 
    # $p.value
    # [1] 1.526151e-18
    

    We can gather them together with something like:

    out <- do.call(rbind.data.frame, lapply(TT1, `[`, c("statistic", "p.value")))
    out
    #      statistic      p.value
    # mpg   18.85693 1.526151e-18
    # cyl   19.59872 5.048147e-19
    # disp  10.53069 9.189065e-12
    

    where mpg and such are row-names. They can be brought in to the frame itself if needed,

    out$name <- rownames(out)
    rownames(out) <- NULL # aesthetics only, not required
    out
    #   statistic      p.value name
    # 1  18.85693 1.526151e-18  mpg
    # 2  19.59872 5.048147e-19  cyl
    # 3  10.53069 9.189065e-12 disp
    

    (Since you made your list of t-tests with apply(MARGIN=1), though, it may not be named meaningfully if the original data did not have good row names.)