【问题标题】:How to extract and combine rows from data frames inside a list in R如何从R中列表内的数据帧中提取和组合行
【发布时间】:2020-07-13 17:57:15
【问题描述】:

我的真实数据分配在一个包含 95 个数据框的大列表中。每个数据框有数千行和 8 列。为了更简单明了,我用虚拟数据创建了这些类似的对象。

state <- c("MG", "SP", "PR")
individual <- c("ind1", "ind2", "ind3")
sample <- c("a", "b", "c")

df1 <- data.frame(var1, state, individual, sample)
df2 <- data.frame(var1, state, individual, sample)
df3 <- data.frame(var1, state, individual, sample)

df_total <- list(df1, df2, df3)

names(df_total) <- c("df1", "df2", "df3")

df_total

#> df_total
#$df1
#        var1 state individual sample
#1  0.3898432    MG       ind1      a
#2 -0.6212406    SP       ind2      b
#3 -2.2146999    PR       ind3      c
#
#$df2
#        var1 state individual sample
#1  0.3898432    MG       ind1      a
#2 -0.6212406    SP       ind2      b
#3 -2.2146999    PR       ind3      c
#
#$df3
#        var1 state individual sample
#1  0.3898432    MG       ind1      a
#2 -0.6212406    SP       ind2      b
#3 -2.2146999    PR       ind3      c

所有数据框的结构都是相同的,包含不同上下文中同一个人的信息。

我的目标是能够从所有数据帧中提取行并将其组合成新的数据帧,同时保留列标题。

更准确地说,我想生成一个数据框,其中包含individual 列上所有提到“ind1”的行,一个包含所有提到“ind2”的行,依此类推。由于我的真实数据中有 95 个不同的人,我想要一个解决方案,它可以循环并为该列中包含的每个不同名称创建一个数据框,而无需单独调用它们。

自从我使用 dplyr 和 purrr 尝试这个已经有几天了,但是失败得很惨……

对初学者有什么建议吗?

【问题讨论】:

  • 看了你的描述,我有些疑惑。是否要基于“个人”列创建新的list

标签: r dataframe dplyr subset purrr


【解决方案1】:

我们可以使用bind_rows.id 来创建一个标识符列,其中包含listnames,然后group_split 与'individual' 列

library(dplyr)
bind_rows(df_total, .id = 'grp')%>% 
        group_split(individual)
#[[1]]
# A tibble: 3 x 5
#   var1 state individual sample grp  
#  <dbl> <fct> <fct>      <fct>  <chr>
#1 0.390 MG    ind1       a      df1  
#2 0.390 MG    ind1       a      df2  
#3 0.390 MG    ind1       a      df3  

#[[2]]
# A tibble: 3 x 5
#    var1 state individual sample grp  
#   <dbl> <fct> <fct>      <fct>  <chr>
#1 -0.621 SP    ind2       b      df1  
#2 -0.621 SP    ind2       b      df2  
#3 -0.621 SP    ind2       b      df3  

#[[3]]
# A tibble: 3 x 5
#   var1 state individual sample grp  
#  <dbl> <fct> <fct>      <fct>  <chr>
#1 -2.21 PR    ind3       c      df1  
#2 -2.21 PR    ind3       c      df2  
#3 -2.21 PR    ind3       c      df3  

【讨论】:

  • 您的解决方案运行良好,@akrun,非常感谢!有没有办法将原始 df 名称的公共部分保留为新 df 的名称?这些名称将出现在新变量“grp”中。
  • @WagnerNogueira 我没有收到你的问题。您是否只需要df 而不是df1df2 等>
【解决方案2】:
lapply(paste0("ind", 1:95), function(y){
  do.call('rbind', lapply(df_total, function(x) x[individual == y, ]))
} )

apply(do.call('rbind', lapply(df_total, function(x) split(x, x$individual))), 2, function(y) do.call('rbind', y))
# $ind1
#          var1 state individual sample
# df1 0.3898432    MG       ind1      a
# df2 0.3898432    MG       ind1      a
# df3 0.3898432    MG       ind1      a
# 
# $ind2
#           var1 state individual sample
# df1 -0.6212406    SP       ind2      b
# df2 -0.6212406    SP       ind2      b
# df3 -0.6212406    SP       ind2      b
# 
# $ind3
#        var1 state individual sample
# df1 -2.2147    PR       ind3      c
# df2 -2.2147    PR       ind3      c
# df3 -2.2147    PR       ind3      c

【讨论】:

    【解决方案3】:

    这是一个基本的 R 解决方案

    res <- split(u<-do.call(rbind,df_total),u$individual)
    

    这样

    > res
    $ind1
               var1 state individual sample
    df1.1 0.3898432    MG       ind1      a
    df2.1 0.3898432    MG       ind1      a
    df3.1 0.3898432    MG       ind1      a
    
    $ind2
                var1 state individual sample
    df1.2 -0.6212406    SP       ind2      b
    df2.2 -0.6212406    SP       ind2      b
    df3.2 -0.6212406    SP       ind2      b
    
    $ind3
             var1 state individual sample
    df1.3 -2.2147    PR       ind3      c
    df2.3 -2.2147    PR       ind3      c
    df3.3 -2.2147    PR       ind3      c
    

    【讨论】:

      猜你喜欢
      • 2020-09-18
      • 2019-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多