根据一列值将 data.frame 一分为二

Posted

技术标签:

【中文标题】根据一列值将 data.frame 一分为二【英文标题】:split data.frame in two based on one column values 【发布时间】: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

谢谢

【问题讨论】:

【参考方案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

【讨论】:

以上是关于根据一列值将 data.frame 一分为二的主要内容,如果未能解决你的问题,请参考以下文章

遍历 pandas 行并根据其他列中的值设置列值

使用 ETL 工具按列值将数据拆分为不定数量的表

根据列值将一行拆分为多行

根据列值将一行分解/拆分为多行

R根据多个列值将数据框子化为多个数据框

Postgres 根据列值将行转置为列