【问题标题】:How to pivot wider multiple columns on dataset and maintain a specific colum order?如何在数据集中旋转更宽的多个列并维护特定的列顺序?
【发布时间】:2022-01-17 09:01:37
【问题描述】:

我的初始数据集

df1 <- structure(list(id = c(1, 1, 2, 3, 3, 3), 
                      name = c("james", "james", "peter", "anne", "anne", "anne"), 
                      trip_id = c(10,11,10,30,11,32),
                      date = c("2021/01/01", "2021/06/01","2021/08/01","2021/10/01","2021/10/21","2021/12/01"),
                      cost = c(100,150,3000,1200,1100,5000)
                      
), 
row.names = c(NA,-6L), 
class = c("tbl_df", "tbl", "data.frame"))

我需要将每次旅行的日期和费用调整得更广,这样它们才能成对出现。我想我更接近了,但希望得到您的反馈。

我当前的代码

df2= df1 %>% pivot_wider(names_from = trip_id, 
                               values_from = c(date, cost))

我想要的结果

df2 <- structure(list(id = c(1, 2, 3), 
                      name = c("james", "peter", "anne"), 
                      date_10 = c("2021/01/01","2021/08/01",NA),
                      cost_10 = c(100,3000,NA),
                      date_11 = c("2021/06/01",NA,"2021/10/21"),
                      cost_11 = c(150,NA,1100),
                      date_30 = c(NA,NA,"2021/10/01"),
                      cost_30 = c(NA,NA,1200),
                      date_32 = c(NA,NA,"2021/12/01"),
                      cost_32 = c(NA,NA,5000)             
                      
), 
row.names = c(NA,-3L), 
class = c("tbl_df", "tbl", "data.frame"))

【问题讨论】:

    标签: r reshape tidyr


    【解决方案1】:

    你拥有它的方式是正确的。除非您有时间序列/面板数据和一些例外情况,否则列编号/行编号不应影响数据。

    否则,您可以使用reshape 函数完成相同的操作,这将为您提供您想要的。标记你这是 Base R:

    reshape(data.frame(df1), timevar = 'trip_id', idvar = c('id', 'name'), dir='wide', sep = '_')
    
      id  name    date_10 cost_10    date_11 cost_11    date_30 cost_30    date_32 cost_32
    1  1 james 2021/01/01     100 2021/06/01     150       <NA>      NA       <NA>      NA
    3  2 peter 2021/08/01    3000       <NA>      NA       <NA>      NA       <NA>      NA
    4  3  anne       <NA>      NA 2021/10/21    1100 2021/10/01    1200 2021/12/01    5000
    

    【讨论】:

      【解决方案2】:

      看起来你很接近。我们在pivot_wider 之前使用trip_id 来帮助重新排序列。您可能需要也可能不需要sort,具体取决于您想要的结果。如果您只想要对,则无需排序。

      library(tidyverse)
      nums <- sort(unique(df1$trip_id))
      nums <- as.character(nums)
      
      df2 <- 
        df1 %>% 
          pivot_wider(names_from = trip_id, 
                      values_from = c(date, cost)) %>%
          select(id, name, ends_with(nums))
      
      df2
      #> # A tibble: 3 x 10
      #>      id name  date_10    cost_10 date_11 cost_11 date_30 cost_30 date_32 cost_32
      #>   <dbl> <chr> <chr>        <dbl> <chr>     <dbl> <chr>     <dbl> <chr>     <dbl>
      #> 1     1 james 2021/01/01     100 2021/0~     150 <NA>         NA <NA>         NA
      #> 2     2 peter 2021/08/01    3000 <NA>         NA <NA>         NA <NA>         NA
      #> 3     3 anne  <NA>            NA 2021/1~    1100 2021/1~    1200 2021/1~    5000
      

      【讨论】:

        【解决方案3】:

        为此,您确实需要额外的pivot_longer 步骤,然后才能将数据形状更改为宽格式。请注意,我在pivot_longer 中使用了values_transform 参数将cost 的类更改为字符,以便我可以将它与中间val 变量中的date 结合起来:

        library(dplyr)
        library(tidyr)
        
        df1 %>%
          pivot_longer(c(date, cost), names_to = "var", 
                       values_to = "val", 
                       values_transform = list(val = as.character)) %>%
          pivot_wider(names_from = c(var, trip_id), values_from = val) %>%
          mutate(across(starts_with("cost"), as.double))
        
        
        # A tibble: 3 x 10
             id name  date_10    cost_10 date_11    cost_11 date_30    cost_30 date_32    cost_32
          <dbl> <chr> <chr>        <dbl> <chr>        <dbl> <chr>        <dbl> <chr>        <dbl>
        1     1 james 2021/01/01     100 2021/06/01     150 NA              NA NA              NA
        2     2 peter 2021/08/01    3000 NA              NA NA              NA NA              NA
        3     3 anne  NA              NA 2021/10/21    1100 2021/10/01    1200 2021/12/01    5000
        

        【讨论】:

          猜你喜欢
          • 2019-04-11
          • 2015-06-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-05
          • 1970-01-01
          相关资源
          最近更新 更多