【问题标题】:Converting each cell in a dataframe column, containing a list, into a row in the dataframe将包含列表的数据框列中的每个单元格转换为数据框中的一行
【发布时间】:2018-09-07 13:14:52
【问题描述】:

我最近一直在使用 R 进行很多工作,但我对列表的经验几乎为零。所以现在我有一个列表,我真的不知道该怎么做。我有一个数据框df,它是通过应用以下函数创建的

df <- data.table(df)[, .(nm = names(.SD),fits = lapply(.SD, function(x) if(is.numeric(x)) summary(lm(y ~ x, na.action=na.omit)))), .SDcols = -1]

它由一个带有变量名称的列和一个带有该变量名称的摘要统计信息列表的列组成,如下所示:

  nm  fits
1 A   list(call = lm(formula = y ~ x, na.action=na.omit))
2 B   list(call = lm(formula = y ~ x, na.action=na.omit))
3 C   list(call = lm(formula = y ~ x, na.action=na.omit))
4 D   list(call = lm(formula = y ~ x, na.action=na.omit))

通过申请:

dfoutput <- lapply(df$fits, function(x) x$coefficients[c(2),])

我得到每个变量的以下示例输出:

       Estimate Std. Error t value Pr(>|t|)    
x      -8.72283    0.68552  -12.72   <2e-16

我想做的是将dfoutput 中的每个列表转换为数据框中的一行,同时考虑变量名称nm 并最好使用列:Estimate Std. Error t value Pr(&gt;|t|)),给我以下示例输出:

Varname Estimate Std. Error t value Pr(>|t|) 
A       -8.72283    0.68552  -12.72   <2e-16
B       -0.72283    0.38552  -12.72   <2e-16
C       -2.72283    0.28552  -12.72   <2e-16
D       -1.72283    1.68552  -12.72   <2e-16

有人能帮我解决这个问题吗?

【问题讨论】:

    标签: r list dataframe lapply


    【解决方案1】:

    我相信你只是想要do.call(rbind, x)

    使用以下构建的数据查看结果:

    do.call(rbind, dfoutput)
    #        Estimate Std. Error   t value     Pr(>|t|)
    # [1,] -0.2233611 0.15508093 -1.440287 1.518983e-01
    # [2,]  0.4089223 0.01889134 21.646019 1.038667e-47
    # [3,]  0.8885803 0.05137355 17.296454 2.325498e-37
    
    cbind(df, do.call(rbind, dfoutput))
    #              nm         fits   Estimate Std. Error   t value     Pr(>|t|)
    # 1:  Sepal.Width <summary.lm> -0.2233611 0.15508093 -1.440287 1.518983e-01
    # 2: Petal.Length <summary.lm>  0.4089223 0.01889134 21.646019 1.038667e-47
    # 3:  Petal.Width <summary.lm>  0.8885803 0.05137355 17.296454 2.325498e-37
    

    数据

    library(data.table)
    y <- iris$Sepal.Length
    df0 <- iris[-5]
    df <- data.table(df0)[, .(nm = names(.SD),fits = lapply(.SD, function(x) if(is.numeric(x)) summary(lm(y ~ x, na.action=na.omit)))), .SDcols = -1]
    # nm         fits
    # 1:  Sepal.Width <summary.lm>
    # 2: Petal.Length <summary.lm>
    # 3:  Petal.Width <summary.lm>
    
    dfoutput <- lapply(df$fits, function(x) x$coefficients[c(2),])
    dfoutput
    # [[1]]
    # Estimate Std. Error    t value   Pr(>|t|) 
    # -0.2233611  0.1550809 -1.4402871  0.1518983 
    # 
    # [[2]]
    # Estimate   Std. Error      t value     Pr(>|t|) 
    # 4.089223e-01 1.889134e-02 2.164602e+01 1.038667e-47 
    # 
    # [[3]]
    # Estimate   Std. Error      t value     Pr(>|t|) 
    # 8.885803e-01 5.137355e-02 1.729645e+01 2.325498e-37 
    

    【讨论】:

    • 这 (cbind(df, do.call(rbind, dfoutput))) 完美运行,非常感谢!
    【解决方案2】:

    使用plyr 包:只需将您的公式替换为ldply

    library(plyr)
    ldply(df$fits,function(x) x$coefficients[c(2),])
    

    输出:

      Estimate Std. Error   t value     Pr(>|t|)
    1 -0.2233611 0.15508093 -1.440287 1.518983e-01
    2  0.4089223 0.01889134 21.646019 1.038667e-47
    3  0.8885803 0.05137355 17.296454 2.325498e-37
    

    【讨论】:

    • 感谢您的回答!有什么方法可以添加变量名吗?
    • @TomKisters:添加变量名是什么意思?添加更多变量?还是使用变量名进行操作?
    【解决方案3】:

    我们可以使用tidyverse

    library(tidyverse)
    map_df(lst1, as.list) 
    # A tibble: 3 x 4
    #  Estimate `Std. Error` `t value` `Pr(>|t|)`
    #     <dbl>        <dbl>     <dbl>      <dbl>
    #1   -0.223       0.155      -1.44   1.52e- 1
    #2    0.409       0.0189     21.6    1.04e-47
    #3    0.889       0.0514     17.3    2.33e-37
    

    如果我们还需要“nm”列,请使用该列命名“lst1”并使用.id

    set_names(lst1, LETTERS[1:3]) %>% 
             map_df(as.list, .id = 'Varname')
    # A tibble: 3 x 5
    #  Varname Estimate `Std. Error` `t value` `Pr(>|t|)`
    #  <chr>      <dbl>        <dbl>     <dbl>      <dbl>
    #1 A         -0.223       0.155      -1.44   1.52e- 1
    #2 B          0.409       0.0189     21.6    1.04e-47
    #3 C          0.889       0.0514     17.3    2.33e-37
    

    【讨论】:

    • 谢谢!有什么方法可以添加nm 列?
    • @TomKisters,如果你用 nm 列命名lst1,即set_names(lst1, nm) %&gt;% map_df(as.list, .id = 'Varname')
    猜你喜欢
    • 1970-01-01
    • 2019-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 2018-05-14
    • 1970-01-01
    相关资源
    最近更新 更多