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

使用~separate after mutate and cross

  •  1
  • TarJae  · 技术社区  · 4 年前

    目的是将所有物种“setosa”行转换为一行“setosa”:(这是一个最小的示例(在实际的更多列和更多组中):

    head(iris, 2) %>%
      select(1,2,5) %>% 
      group_by(Species)
    
      Sepal.Length Sepal.Width Species
             <dbl>       <dbl> <fct>  
    1          5.1         3.5 setosa 
    2          4.9         3   setosa 
    

    我用 summarise 具有 toString 得到:

      Species Sepal.Length Sepal.Width
      <fct>   <chr>        <chr>      
    1 setosa  5.1, 4.9     3.5, 3  
    

      Species Sepal.Length1 Sepal.Length2 Sepal.Width1 Sepal.Width2
      <fct>           <dbl>         <dbl>        <dbl>        <int>
    1 setosa            5.1           4.9          3.5            3
    

    head(iris, 2) %>%
      select(1,2,5) %>% 
      group_by(Species) %>% 
      summarise(across(everything(), ~toString(.))) %>% 
      ungroup() %>% 
      separate(Sepal.Length, c("Sepal.Length1", "Sepal.Length2"),  sep = ", ", convert = TRUE) %>% 
      separate(Sepal.Width, c("Sepal.Width1", "Sepal.Width2"),  sep = ", ", convert = TRUE)
    

    然而,我希望能够使用 separate 之后 mutate across 使用匿名函数时,此代码无效:

    head(iris, 2) %>%
      select(1,2,5) %>% 
      group_by(Species) %>% 
      summarise(across(everything(), ~toString(.))) %>% 
      ungroup() %>% 
      mutate(across(-1, ~separate(., into = paste0(., 1:2), sep = ", ", convert = TRUE)))
    
    Error: Problem with `mutate()` input `..1`.
    i `..1 = across(-1, ~separate(., into = paste0(., 1:2), sep = ", ", convert = TRUE))`.
    x no applicable method for 'separate' applied to an object of class "character"
    

    如何申请 功能后 变异

    2 回复  |  直到 4 年前
        1
  •  2
  •   Jon Spring    4 年前

    另一种方法是长旋转、变换和再次宽旋转。

    library(tidyverse)
    head(iris, 2) %>%
      select(1,2,5) %>% 
    
      pivot_longer(-Species) %>%
      group_by(name) %>% mutate(col = paste0(name, row_number())) %>% ungroup() %>%
      select(-name) %>%
      arrange(col) %>%  # for ordering columns like OP
      pivot_wider(names_from = col, values_from = value)
    
    
    # A tibble: 1 x 5
      Species Sepal.Length1 Sepal.Length2 Sepal.Width1 Sepal.Width2
      <fct>           <dbl>         <dbl>        <dbl>        <dbl>
    1 setosa            5.1           4.9          3.5            3
    
        2
  •  1
  •   akrun    4 年前

    separate tibble 然后呢 分离 across 最后 unnest list 输出

    library(dplyr)
    library(tidyr)
    library(stringr)
    head(iris, 2) %>%
      select(1,2,5) %>% 
      group_by(Species) %>% 
      summarise(across(everything(), ~toString(.)), .groups = 'drop') %>%
      mutate(across(-1, ~ list(tibble(col1 = .) %>% 
            separate(col1, into = str_c(cur_column(), 1:2), sep = ",\\s+")))) %>% 
      unnest(cols = c(Sepal.Length, Sepal.Width))
    

    -输出

    # A tibble: 1 × 5
      Species Sepal.Length1 Sepal.Length2 Sepal.Width1 Sepal.Width2
      <fct>   <chr>         <chr>         <chr>        <chr>       
    1 setosa  5.1           4.9           3.5          3           
    
        3
  •  0
  •   PaulS    4 年前

    另一个解决方案:

    library(tidyverse)
    
    head(iris, 2) %>%
      select(1,2,5) %>% 
      group_by(Species) %>% 
      summarise(across(everything(), ~toString(.))) %>% 
      separate(2, into = paste0("Sepal.Length",1:2),  sep=", ") %>% 
      separate(4, into = paste0("Sepal.Width",1:2),  sep=", ")
    
    #> # A tibble: 1 × 5
    #>   Species Sepal.Length1 Sepal.Length2 Sepal.Width1 Sepal.Width2
    #>   <fct>   <chr>         <chr>         <chr>        <chr>       
    #> 1 setosa  5.1           4.9           3.5          3
    
    推荐文章