【问题标题】:Put result from lapply with different columns to one data frame将具有不同列的 lapply 结果放入一个数据帧
【发布时间】:2017-12-20 21:43:07
【问题描述】:

我正在处理一个数据集,并希望对一些变量进行一些描述性统计,并将它们放在一个数据框中。 我可以处理这样的情况:

dt<-data.frame('X1'=rnorm(10),
           'X2'=rnorm(10))
temp<-do.call(rbind, lapply(dt, summary))

还有这样的情况:

dt<-data.frame('X1'=rnorm(10),
           'X2'=rnorm(10))
dt[1,2]<-NA
dt[2,1]<-NA
temp<-do.call(rbind, lapply(dt, summary))

但是遇到下面这样的情况,我就不行了:

dt<-data.frame('X1'=rnorm(10),
           'X2'=rnorm(10))
dt[1,2]<-NA
temp<-do.call(rbind, lapply(dt, summary))

当某些变量包含 NA 而某些不包含时,不同变量的 lapply 的结果将具有不同的列:

> lapply(dt, summary)
$X1
      Min.    1st Qu.     Median       Mean    3rd Qu.       Max. 
-0.7821000 -0.2881000 -0.0003675  0.3195000  0.8114000  2.0230000 

$X2
     Min.   1st Qu.    Median      Mean   3rd Qu.      Max.      NA's 
-1.336000 -0.604000 -0.005283  0.008491  0.784300  1.407000         1 

在这种情况下,rbind 将不再起作用。我确实意识到rbnd.fill 可以在数据帧具有不同列时进行行绑定,但将每个变量的结果传输到数据帧然后通过rbind.fill 将它们组合起来会有点乏味,我相信有给定 R 拥有的权力的一种命令解决方案。

希望有人可以帮助我,您的时间和知识将不胜感激!

【问题讨论】:

    标签: r lapply rbind


    【解决方案1】:

    您可以将rbind.fillbroom 包中的tidy 组合起来,一次性获得,即

    plyr::rbind.fill(lapply(dt, function(i) broom::tidy(summary(i))))
    #    minimum         q1     median        mean         q3   maximum na
    #1 -1.621968 -0.7001894 -0.2062857  0.06791479  0.5987752 2.4195609 NA
    #2 -2.061762 -1.3925008 -1.1702881 -0.94991206 -0.9249380 0.6052219  1
    

    【讨论】:

    • 非常感谢@Sotos,一个绝妙的解决方案完美运行。我会把它当作答案!
    【解决方案2】:

    使用 tidyverse 方式的答案,即purrr 主要是:

    dt<-data.frame('X1'=rnorm(10),
                   'X2'=rnorm(10))
    dt[1,2]<-NA
    
    library(purrr)
    library(broom)
    dt %>%
      map(., summary) %>%
      map_df(broom::tidy)
    #>     minimum         q1     median       mean        q3  maximum na
    #> 1 -0.798480  0.5869163 0.89381256  0.9626454 1.6942529 2.218769 NA
    #> 2 -1.331122 -1.0149286 0.05946167 -0.1562312 0.5235401 1.061640  1
    

    对于您正在做的事情,您还可以对ropensci 社区正在进行的关于skimr 包的工作感兴趣。它尚未在 CRAN 上,但在 github 上。它旨在简化汇总统计的使用,兼容 tidyverse 方法

    # devtools::install_github("ropenscilabs/skimr")
    dt %>% skimr::skim()
    #> Numeric Variables
    #> # A tibble: 2 x 13
    #>     var    type missing complete     n       mean        sd       min
    #>   <chr>   <chr>   <dbl>    <dbl> <dbl>      <dbl>     <dbl>     <dbl>
    #> 1    X1 numeric       0       10    10  0.9626454 0.9001430 -0.798480
    #> 2    X2 numeric       1        9    10 -0.1562312 0.8539957 -1.331122
    #> # ... with 5 more variables: `25% quantile` <dbl>, median <dbl>, `75%
    #> #   quantile` <dbl>, max <dbl>, hist <chr>
    

    【讨论】:

    • 感谢@cderv,第一个解决方案完美运行。还没有测试第二个。虽然无法回答,但我会提出来。
    • 想提一下,skimr 现在在 CRAN 上。它有一个函数skim_to_wide(),它返回单个数据帧,其中不适用数据类型的统计信息设置为NA。不过,所有变量都是字符,因此它们的格式正确。
    【解决方案3】:

    仅使用plyr 包,您可以使用强制as 系列函数与plyr::rbind.fill 一起使用与您的原始帖子类似的代码来完成您想要的事情。 plyr::rbind.fill 需要一个 data.frame,因此我们首先将 summary(命名向量)的输出转换为一个列表,然后使用 as.data.frame.list 转换为一个 data.frame。

    do.call(plyr::rbind.fill, lapply(dt, function(x) as.data.frame.list(summary(x))))
    

    返回

            Min.   X1st.Qu.     Median        Mean    X3rd.Qu.      Max. NA.s
    1 -1.3228095 -0.9366220  0.3869426  0.05838389  0.85474059 1.1721839   NA
    2 -0.8421435 -0.5083617 -0.4801625 -0.29357112 -0.02549078 0.4506287    1
    

    【讨论】:

    • 感谢@Imo,优雅的单行解决方案。从来没有意识到这种操作。
    • 您可以通过在控制台中键入 as. 然后按 TAB 键来查看 R 中大量的 as. 系列函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-15
    • 2014-06-04
    • 2023-04-06
    • 2021-02-15
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多