【问题标题】:Using pivot_longer to re-shape data from wide to long [duplicate]使用 pivot_longer 将数据从宽到长重新整形[重复]
【发布时间】:2020-05-08 11:55:03
【问题描述】:

我想使用 pivot_longer 重新塑造这个数据框 -

# A tibble: 5 x 7
  PizzaNumber Topping_1 Category_1  Topping_2 Category_2  Topping_3 Category_3 
        <int> <fct>     <fct>       <fct>     <fct>       <fct>     <fct>      
1           1 cheese    vegetarian  ham       carnivorous tomato    vegetarian 
2           2 spinach   vegetarian  tomato    vegetarian  NA        NA         
3           3 pineapple vegetarian  cheese    vegetarian  ham       carnivorous
4           4 cheese    vegetarian  tomato    vegetarian  NA        NA         
5           5 beef      carnivorous NA        NA          NA        NA  

变成如下长格式-

# A tibble: 11 x 3
   PizzaNumber Topping   Category   
         <int> <fct>     <fct>      
 1           1 cheese    vegetarian 
 2           1 ham       carnivorous
 3           1 tomato    vegetarian 
 4           2 spinach   vegetarian 
 5           2 tomato    vegetarian 
 6           3 pineapple vegetarian 
 7           3 cheese    vegetarian 
 8           3 ham       carnivorous
 9           4 cheese    vegetarian 
10           4 tomato    vegetarian 
11           5 beef      carnivorous

有人可以帮我编写代码来实现这一点吗?到目前为止,我的尝试导致一团糟。

宽数据框代码如下-

> dput(widedata)
structure(list(PizzaNumber = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 
4L, 4L, 5L), Topping = structure(c(2L, 3L, 6L, 5L, 6L, 4L, 2L, 
3L, 2L, 6L, 1L), .Label = c("beef", "cheese", "ham", "pineapple", 
"spinach", "tomato"), class = "factor"), Category = structure(c(2L, 
1L, 2L, 2L, 2L, 2L, 2L, 1L, 2L, 2L, 1L), .Label = c("carnivorous", 
"vegetarian"), class = "factor")), class = "data.frame", row.names = c(NA, 
-11L))

【问题讨论】:

    标签: r tidyverse tidyr


    【解决方案1】:

    我们可以通过 dplyrtidyrpurrr 的组合来做到这一点:

    library(dplyr) # 1.0.0
    library(tidyr) # 1.1.0
    library(purrr) # 0.3.4
    
    widedata %>% group_by(PizzaNumber) %>% nest() %>%
            mutate(
                    Topping_Category = map(data, function(data) {
                            as.list(paste(data[, c(1, 3, 5)], data[, c(2, 4, 6)], sep = "_"))
                    })) %>% select(-data) %>%
            unnest_longer(Topping_Category, indices_include = FALSE) %>%
            ungroup() %>%
            separate(Topping_Category, c("Topping", "Category"), sep = "_") %>%
            mutate(Topping = na_if(Topping, "NA"), Category = na_if(Category, "NA")) %>%
            filter(Topping != is.na(Topping))
    
    # A tibble: 11 x 3
       PizzaNumber Topping   Category   
             <dbl> <chr>     <chr>      
     1           1 cheese    vegetarian 
     2           1 ham       carnivorous
     3           1 tomato    vegetarian 
     4           2 spinach   vegetarian 
     5           2 tomato    vegetarian 
     6           3 pineapple vegetarian 
     7           3 cheese    vegetarian 
     8           3 ham       carnivorous
     9           4 cheese    vegetarian 
    10           4 tomato    vegetarian 
    11           5 beef      carnivorous
    

    顺便说一句,您使用dput(widedata) 提供的数据实际上是您想要的长格式。

    这里是实际开始widedata

    structure(list(PizzaNumber = c("1", "2", "3", "4", "5"), Topping_1 = c("cheese", 
    "spinach", "pineapple", "cheese", "beef"), Category_1 = c("vegetarian", 
    "vegetarian", "vegetarian", "vegetarian", "carnivorous"), Topping_2 = c("ham", 
    "tomato", "cheese", "tomato", NA), Category_2 = c("carnivorous", 
    "vegetarian", "vegetarian", "vegetarian", NA), Topping_3 = c("tomato", 
    NA, "ham", NA, NA), Category_3 = c("vegetarian", NA, "carnivorous", 
    NA, NA)), row.names = c(NA, -5L), class = c("tbl_df", "tbl", 
    "data.frame"))
    

    【讨论】:

      【解决方案2】:

      有了pivot_longer,你可以做到-

      tidyr::pivot_longer(df, cols = -PizzaNumber, 
                          names_to = '.value', 
                          names_pattern = '(\\w+)_\\d+', 
                          values_drop_na = TRUE)
      
      #  PizzaNumber Topping   Category   
      #   <chr>       <chr>     <chr>      
      # 1 1           cheese    vegetarian 
      # 2 1           ham       carnivorous
      # 3 1           tomato    vegetarian 
      # 4 2           spinach   vegetarian 
      # 5 2           tomato    vegetarian 
      # 6 3           pineapple vegetarian 
      # 7 3           cheese    vegetarian 
      # 8 3           ham       carnivorous
      # 9 4           cheese    vegetarian 
      #10 4           tomato    vegetarian 
      #11 5           beef      carnivorous
      

      【讨论】:

        猜你喜欢
        • 2021-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 1970-01-01
        • 2012-12-01
        • 2011-03-20
        相关资源
        最近更新 更多