【问题标题】:Add the numeric part of names for list of dataframes as a column将数据框列表的每个元素的名称添加为一列
【发布时间】:2019-10-29 16:52:42
【问题描述】:

我有一个数据列表。在此列表中,它是数据表或数据框。这个问题之后,我会绑定列表。

数据示例:

players
$`0001playeraway`
      key NO        MIN 2PTM 2PTA 2PT(%) 3PTM 3PTA 3PT(%) FGM FGA FG(%) FTM FTA FT(%) OR DR REB AST TO STL BS PF
   1:   * 17   40:00:00    9   15     60    0    0      0   9  15    60   2   4    50  1  8   9   2  4   1  2  1
   2:   * 16   40:00:00    4    8     50    8   13     62  12  21    57  20  22    91  2  3   5   4  4   0  0  3
   3:   * 10   33:02:00    2    4     50    0    3      0   2   7    29   0   0     0  0  4   4   1  3   1  0  4
   4:   *  3   27:46:00    2    3     67    0    0      0   2   3    67   6   6   100  1  4   5   0  1   4  0  3
   5:      1   26:24:00    1    1    100    0    2      0   1   3    33   1   2    50  1  0   1   1  0   1  0  4

$`0102playeraway`
      key NO        MIN 2PTM 2PTA 2PT(%) 3PTM 3PTA 3PT(%) FGM FGA FG(%) FTM FTA FT(%) OR DR REB AST TO STL BS PF
   1:   *  9   40:00:00    1    3     33    2    7     29   3  10    30   3   4    75  1  4   5   8  1   4  1  3
   2:   * 53   38:18:00    6   14     43    0    0      0   6  14    43   6   8    75  5  3   8   3  4   0  2  5
   3:   * 13   35:16:00    3    8     38    1    2     50   4  10    40   2   5    40  1  3   4   5  0   0  0  5
   4:   * 23   31:42:00    2    7     29    2    8     25   4  15    27   7   7   100  1  7   8   1  1   0  0  2
   5:     14      22:08    2    3     67    2    4     50   4   7    57   0   0     0  0  2   2   2  1   0  0  1

其余部分省略。

如何为列表中的数据表名称赋值?

所需的输出:

players
$`0001playeraway`
      year key NO        MIN 2PTM 2PTA 2PT(%) 3PTM 3PTA 3PT(%) FGM FGA FG(%) FTM FTA FT(%) OR DR REB AST TO STL BS PF
   1: 0001  * 17   40:00:00    9   15     60    0    0      0   9  15    60   2   4    50  1  8   9   2  4   1  2  1
   2: 0001  * 16   40:00:00    4    8     50    8   13     62  12  21    57  20  22    91  2  3   5   4  4   0  0  3
   3: 0001  * 10   33:02:00    2    4     50    0    3      0   2   7    29   0   0     0  0  4   4   1  3   1  0  4
   4: 0001  *  3   27:46:00    2    3     67    0    0      0   2   3    67   6   6   100  1  4   5   0  1   4  0  3
   5: 0001     1   26:24:00    1    1    100    0    2      0   1   3    33   1   2    50  1  0   1   1  0   1  0  4

$`0102playeraway`
      year key NO        MIN 2PTM 2PTA 2PT(%) 3PTM 3PTA 3PT(%) FGM FGA FG(%) FTM FTA FT(%) OR DR REB AST TO STL BS PF
   1: 0102  *  9   40:00:00    1    3     33    2    7     29   3  10    30   3   4    75  1  4   5   8  1   4  1  3
   2: 0102  * 53   38:18:00    6   14     43    0    0      0   6  14    43   6   8    75  5  3   8   3  4   0  2  5
   3: 0102  * 13   35:16:00    3    8     38    1    2     50   4  10    40   2   5    40  1  3   4   5  0   0  0  5
   4: 0102  * 23   31:42:00    2    7     29    2    8     25   4  15    27   7   7   100  1  7   8   1  1   0  0  2
   5: 0102    14      22:08    2    3     67    2    4     50   4   7    57   0   0     0  0  2   2   2  1   0  0  1

【问题讨论】:

    标签: r list dataframe datatable


    【解决方案1】:

    你可以在一个简单的Map 和substr 中做到这一点;无需额外的软件包。

    L 应作为data.frames 和data.tables 混合列表的示例:

    L
    # $`0001playeraway`
    # X1 X2 X3 X4
    # 1  1  4  7 10
    # 2  2  5  8 11
    # 3  3  6  9 12
    # 
    # $`0102playeraway`
    # X1 X2 X3 X4
    # 1  1  4  7 10
    # 2  2  5  8 11
    # 3  3  6  9 12
    # 
    # $`1003playeraway`
    # X1 X2 X3 X4
    # 1:  1  4  7 10
    # 2:  2  5  8 11
    # 3:  3  6  9 12
    

    方法:

    library(data.table)
    dat <- do.call(rbind, Map(function(x) cbind(year=substr(names(L)[x], 1, 4), L[[x]]), seq(L)))
    dat
    #    year X1 X2 X3 X4
    # 1: 0001  1  4  7 10
    # 2: 0001  2  5  8 11
    # 3: 0001  3  6  9 12
    # 4: 0102  1  4  7 10
    # 5: 0102  2  5  8 11
    # 6: 0102  3  6  9 12
    # 7: 1003  1  4  7 10
    # 8: 1003  2  5  8 11
    # 9: 1003  3  6  9 12
    

    由于data.table 主导整个过程,如果您想在之后使用data.frame,请执行dat &lt;- as.data.frame(dat)。

    数据

    L <- list(`0001playeraway` = structure(list(X1 = 1:3, X2 = 4:6, X3 = 7:9, 
        X4 = 10:12), class = "data.frame", row.names = c(NA, -3L)), 
        `0102playeraway` = structure(list(X1 = 1:3, X2 = 4:6, X3 = 7:9, 
            X4 = 10:12), class = "data.frame", row.names = c(NA, 
        -3L)), `1003playeraway` = structure(list(X1 = 1:3, X2 = 4:6, 
            X3 = 7:9, X4 = 10:12), class = c("data.table", "data.frame"
        ), row.names = c(NA, -3L)))
    

    【讨论】:

      【解决方案2】:

      由于您无论如何都计划绑定数据帧,因此您可以跳过一两步,方法是使用 dplyr 的 bind_rows 和参数 .id = "year" 将列表元素名称包含为新变量 year。使用数据:

      library(data.table)
      
      players <- list(`0001playeraway` = data.table(NO = 1:5),
                      `0102playeraway` = data.table(NO = 6:10)
                      )
      

      你可以这样做:

      library(dplyr)
      
      bind_rows(players, .id = "year")
      

      返回:

                   year NO
      1  0001playeraway  1
      2  0001playeraway  2
      3  0001playeraway  3
      4  0001playeraway  4
      5  0001playeraway  5
      6  0102playeraway  6
      7  0102playeraway  7
      8  0102playeraway  8
      9  0102playeraway  9
      10 0102playeraway 10
      

      如果你真的只想要数字,你可以使用df$year &lt;- sub("(\\d+).*", "\\1", df$year) 之类的东西,或者只是将bind_rows 的输出通过管道传输到mutate,例如:

      bind_rows(players, .id = "year") %>%
          mutate(year = sub("(\\d+).*", "\\1", year))
      

      返回:

         year NO
      1  0001  1
      2  0001  2
      3  0001  3
      4  0001  4
      5  0001  5
      6  0102  6
      7  0102  7
      8  0102  8
      9  0102  9
      10 0102 10
      

      请注意,这将返回 data.frame。如果您需要data.table,只需将mutate 的输出通过管道传输到as.data.table。

      【讨论】:

        【解决方案3】:

        您可以使用purrr::imap 和dplyr::mutate 为列表中的所有数据框添加一列,其中包含每个元素的名称。在这里,我还使用sringr::str_extract 来根据需要获取名称的数字部分。

        #some data to work with as an example:
        df1 <- data.frame(x = 1:3, y=letters[1:3])
        listdfs <- list("tr088text" = df1,"character963" = df1,"00123string" = df1)
        
        library(tidyverse)
        
        imap(listdfs, ~mutate(year = str_extract(.y, "\\-*\\d+\\.*\\d*") , .x))
        
        #> $tr088text
        #>   x y year
        #> 1 1 a  088
        #> 2 2 b  088
        #> 3 3 c  088
        #> 
        #> $character963
        #>   x y year
        #> 1 1 a  963
        #> 2 2 b  963
        #> 3 3 c  963
        #> 
        #> $`00123string`
        #>   x y  year
        #> 1 1 a 00123
        #> 2 2 b 00123
        #> 3 3 c 00123
        

        由reprex package (v0.3.0) 于 2019 年 6 月 15 日创建

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-28
          • 2018-08-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多