【问题标题】:split data.frame in two based on one column values根据一列值将 data.frame 一分为二
【发布时间】:2022-01-17 18:50:09
【问题描述】:

假设我有一个 data.frame df 如下:

df=data.frame(one=c(1,2,3,4,5,6,7), 
two=c('a','a','a','b','b','b','b'), 
three=c(1123,33,5566,212,1,90,876))

我需要根据two 列的值将df 拆分为两部分,即ab

这是我想要的输出:

  one.x two.x three.x one.y two.y three.y
   1      a    1123     4     b      212 
   2      a      33     5     b        1
   3      a    5566     6     b       90
  NA     NA      NA     7     b      876

谢谢

【问题讨论】:

    标签: r dataframe split rows


    【解决方案1】:

    这是一个使用zoo::cbind.zoo的想法,

    do.call(zoo::cbind.zoo, split(df, df$two))
    
    #  one.a two.a three.a one.b two.b three.b
    #1 1     a     1123    4     b     212    
    #2 2     a       33    5     b       1    
    #3 3     a     5566    6     b      90    
    #4 <NA>  <NA>  <NA>    7     b     876
    

    【讨论】:

      【解决方案2】:

      基本 R 选项

      lst <- split(df, ~two)
      nmax <- max(sapply(lst, nrow))
      do.call(
        cbind,
        lapply(
          lst,
          function(x) {
            k <- nrow(x)
            x[k + seq_len(nmax - k), ] <- NA
            x
          }
        )
      )
      

      给予

        a.one a.two a.three b.one b.two b.three
      1     1     a    1123     4     b     212
      2     2     a      33     5     b       1
      3     3     a    5566     6     b      90
      4    NA  <NA>      NA     7     b     876
      

      【讨论】:

        【解决方案3】:

        tidyverse 解决方案:

        library(tidyverse)
        
        df=data.frame(one=c(1,2,3,4,5,6,7), 
                      two=c('a','a','a','b','b','b','b'), 
                      three=c(1123,33,5566,212,1,90,876))
        
        df %>% 
          group_by(two) %>% 
          add_count %>% 
          mutate(id = cur_group_id()) %>% 
          ungroup %>% 
          mutate(n = max(n)) %>% 
          group_by(two) %>% 
          group_split %>% 
          map_dfc(~ if (nrow(.x) < unique(.x$n)) {add_row(.x)} else {.x} %>% 
                     set_names(., str_c(names(.), unique(.$id)))) %>% 
          ungroup %>% select(!starts_with(c("n","id")))
        
        #> # A tibble: 4 × 6
        #>     one two   three  one2 two2  three2
        #>   <dbl> <chr> <dbl> <dbl> <chr>  <dbl>
        #> 1     1 a      1123     4 b        212
        #> 2     2 a        33     5 b          1
        #> 3     3 a      5566     6 b         90
        #> 4    NA <NA>     NA     7 b        876
        

        【讨论】:

          猜你喜欢
          • 2019-08-07
          • 2016-02-10
          • 1970-01-01
          • 1970-01-01
          • 2021-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-26
          相关资源
          最近更新 更多