【问题标题】:Splitting and creating 2 rows out of one in R data table在 R 数据表中拆分和创建 2 行
【发布时间】:2020-05-08 12:12:21
【问题描述】:

我在 R 中有一个这样的数据集 (dt):

n       id      val
1       1&&2    10
2       3       20
3       4&&5    30

而我想要得到的是

n       id      val
1       1       10
2       2       10
3       3       20
4       4       30
5       5       30

我知道要拆分 ID,我需要执行以下操作: id_split <- strsplit(dt$id,"&&")

但是如何为最初连续在一起的 id 创建具有相同 val 的新行?

【问题讨论】:

    标签: r datatable


    【解决方案1】:

    你可以cbind拆分得到一个你cbind的列再次到val(回收)。

    res <- do.call(rbind, Map(data.frame, id=lapply(strsplit(dat$id, "&&"), cbind), 
                              val=dat$val))
    res <- cbind(n=1:nrow(res), res)
    res
    #   n id val
    # 1 1  1  10
    # 2 2  2  10
    # 3 3  3  20
    # 4 4  4  30
    # 5 5  5  30
    

    【讨论】:

      【解决方案2】:

      您可以使用id 拆分中的lengths 并扩展您的行。然后将n 设置为数据帧长度的序列,即

      l1 <- strsplit(as.character(df$id), '&&')
      res_df <- transform(df[rep(seq_len(nrow(df)), lengths(l1)),], 
                          id = unlist(l1), 
                          n = seq_along(unlist(l1)))
      

      给出,

          n id val
      1   1  1  10
      1.1 2  2  10
      2   3  3  20
      3   4  4  30
      3.1 5  5  30
      

      您可以使用rownames(res_df) &lt;- NULL 删除行名

      【讨论】:

        【解决方案3】:

        data.table 解决方案。

        library(data.table)
        DT <- fread('n       id      val
        1       1&&2    10
        2       3       20
        3       4&&5    30')
        
        
        DT[,.(id=unlist(strsplit(id,split ="&&"))),by=.(n,val)][,n:=.I][]
        #>    n val id
        #> 1: 1  10  1
        #> 2: 2  10  2
        #> 3: 3  20  3
        #> 4: 4  30  4
        #> 5: 5  30  5
        

        reprex package (v0.3.0) 于 2020 年 5 月 8 日创建

        注意:

        更多的 rebosut 解决方案是by = 1:nrow(DT)。但是你需要在你的其他专栏中玩耍。

        【讨论】:

          【解决方案4】:

          如果有人在寻找整洁的解决方案,

          dt %>%
            separate(id, into = paste0("id", 1:2),sep = "&&") %>% 
            pivot_longer(cols = c(id1,id2), names_to = "id_name", values_to = "id") %>% 
            drop_na(id) %>% 
            select(n, id, val)
          

          输出为

          # A tibble: 5 x 3
                n id      val
            <dbl> <chr> <dbl>
          1     1 1        10
          2     1 2        10
          3     2 3        20
          4     3 4        30
          5     3 5        30
          

          编辑: 正如@sotos 所建议的那样,我完全错过了。一个班轮解决方案

          d %>% separate_rows(id, ,sep = "&&")
          

          输出与

          相同
          # A tibble: 5 x 3
                n id      val
            <dbl> <chr> <dbl>
          1     1 1        10
          2     1 2        10
          3     2 3        20
          4     3 4        30
          5     3 5        30
          

          【讨论】:

          • 你也可以dt %&gt;% separate_rows(id, sep = '&amp;&amp;')
          【解决方案5】:

          tstrplit by id from data.table 可以完成这项工作

          library(data.table)
          df <- setDT(df)[,.('id' = tstrsplit(id, "&&")), by = c('n','val')]
          df[,'n' := seq(.N)]
          
          df
             n val id
          1: 1  10  1
          2: 2  10  2
          3: 3  20  3
          4: 4  30  4
          5: 5  30  5
          

          【讨论】:

            猜你喜欢
            • 2018-04-17
            • 1970-01-01
            • 1970-01-01
            • 2021-04-15
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多