代码之家  ›  专栏  ›  技术社区  ›  hmg

当某些键有多个值时,使用tidyr::pivot_

  •  0
  • hmg  · 技术社区  · 4 年前

    df <- data.frame(ColA=c("A", "B", "B", "C"), ColB=letters[23:26])
    
      ColA ColB
    1    A    w
    2    B    x
    3    B    y
    4    C    z
    

      ColA ColB
    1    A    w
    2    B    xy
    3    C    z
    

    常客 pivot_wider() 将引发警告并将值转换为列表:

    df.wide <- df %>%
        pivot_wider(names_from=ColA, values_from=ColB)
    
    Warning message:
    Values are not uniquely identified; output will contain list-cols.
    * Use `values_fn = list` to suppress this warning.
    * Use `values_fn = length` to identify where the duplicates arise
    * Use `values_fn = {summary_fun}` to summarise duplicates 
    
    # A tibble: 1 x 3
      A         B         C        
      <list>    <list>    <list>   
    1 <chr [1]> <chr [2]> <chr [1]>
    

    根据警告,它看起来像 支点() value_fn() 类似于我想要的中间步骤:

    # intermediate step
    df.wide <- df %>%
        pivot_wider(names_from=ColA, values_from=ColB, values_fn=SOMETHING)
    
       A  B  C
    1  w  xy z
    

    values_fn() 只接受摘要函数,而不是处理字符数据的函数(如 paste() )

    我能得到的最接近的结果是:

    df %>%
      pivot_wider(names_from=ColA, values_from=ColB, values_fn=list) %>% 
      mutate(across(everything(), as.character)) %>%
      pivot_longer(cols=everything(), names_to="ColA", values_to="ColB")
    
    # A tibble: 3 x 2
      ColA  ColB             
      <chr> <chr>            
    1 A     "w"              
    2 B     "c(\"x\", \"y\")"
    3 C     "z" 
    

    带着额外的变异 gsub() -类型函数。当然还有更简单的方法!最好在 tidyverse ,但也对其他软件包开放。

    谢谢

    1 回复  |  直到 4 年前
        1
  •  1
  •   neilfws    4 年前

    我不认为您需要在这里进行透视,除非您的实际数据比所示的示例更复杂。

    library(dplyr)
    
    df %>% 
      group_by(ColA) %>% 
      summarise(ColB = paste0(ColB, collapse = ""))
    

    结果:

    # A tibble: 3 × 2
      ColA  ColB 
      <chr> <chr>
    1 A     w    
    2 B     xy   
    3 C     z