Merging multiple rows into single row

后端 未结 2 1015
慢半拍i
慢半拍i 2021-01-16 04:26

I\'ve some problems with my data frame in R. My data frame looks something like this:

ID  TIME    DAY        URL_NAME      VALUE  TIME_SPEND
1    12:15  Mond         


        
相关标签:
2条回答
  • 2021-01-16 04:37

    I'd recommend using dcast from the "data.table" package, which would allow you to reshape multiple measure variables at once.

    Example:

    library(data.table)
    as.data.table(mydf)[, dcast(.SD, ID ~ rowid(ID), value.var = names(mydf)[-1])]
    #    ID TIME_1 TIME_2 TIME_3   DAY_1   DAY_2    DAY_3 URL_NAME_1 URL_NAME_2 URL_NAME_3 VALUE_1 VALUE_2
    # 1:  1  12:15  13:15  15:00  Monday Tuesday Thursday       HOME  CUSTOMERS     PLANTS       4       5
    # 2:  2  14:15  10:19     NA Tuesday  Monday       NA  CUSTOMERS  CUSTOMERS         NA       2       9
    #    VALUE_3 TIME_SPEND_1 TIME_SPEND_2 TIME_SPEND_3
    # 1:       8           30           19           40
    # 2:      NA           21            8           NA
    

    Here's the sample data used:

    mydf <- data.frame(
      ID = c(1, 1, 1, 2, 2),
      TIME = c("12:15", "13:15", "15:00", "14:15", "10:19"),
      DAY = c("Monday", "Tuesday", "Thursday", "Tuesday", "Monday"),
      URL_NAME = c("HOME", "CUSTOMERS", "PLANTS", "CUSTOMERS", "CUSTOMERS"),
      VALUE = c(4, 5, 8, 2, 9),
      TIME_SPEND = c(30, 19, 40, 21, 8)
    )
    mydf
    #   ID  TIME      DAY  URL_NAME VALUE TIME_SPEND
    # 1  1 12:15   Monday      HOME     4         30
    # 2  1 13:15  Tuesday CUSTOMERS     5         19
    # 3  1 15:00 Thursday    PLANTS     8         40
    # 4  2 14:15  Tuesday CUSTOMERS     2         21
    # 5  2 10:19   Monday CUSTOMERS     9          8
    
    0 讨论(0)
  • 2021-01-16 04:43

    Try this tidyverse solution which will produce an output close to what you want. You can group by TIME then create a sequential id that will identify the future columns. After that reshape to long (pivot_longer()) combine the variable name with the id and then reshape to wide (pivot_wider()). Here's the code where I have used a dataset of my own,

    df1 <- data.frame(Components = c(rep("ABC",5),rep("BCD",5)), 
                  Size = c(sample(1:100,5),sample(45:100,5)),
                  Age = c(sample(1:100,5),sample(45:100,5)))
    

    For the above-generated data set, the following code piece is the solution:

    library(tidyverse)
    #Code
    newdf <- df1 %>% group_by(Components) %>% mutate(id=row_number()) %>%
      pivot_longer(-c(Components,id)) %>%
      mutate(name=paste0(name,'.',id)) %>% select(-id) %>%
      pivot_wider(names_from = name,values_from=value)
    

    OUTPUT would look like:

    # A tibble: 2 x 11
    # Groups:   Components [2]
      Components Size.1 Age.1 Size.2 Age.2 Size.3 Age.3 Size.4 Age.4 Size.5 Age.5
      <fct>       <int> <int>  <int> <int>  <int> <int>  <int> <int>  <int> <int>
    1 ABC            23    94     52    89     15    25     76    38     33    99
    2 BCD            59    62     55    81     81    61     80    83     97    68
    

    ALTERNATIVE SOLUTION:

    We could use unite to unite the columns and then use pivot_wider

    library(dplyr)
    library(tidyr)
    library(data.table)
    df1 %>%
       mutate(rn = rowid(Components)) %>%
       pivot_longer(cols = Size:Age) %>% 
       unite(name, name, rn, sep=".") %>%
       pivot_wider(names_from = name, values_from = value)
    

    OUTPUT would look like:

    # A tibble: 2 x 11
    #  Components Size.1 Age.1 Size.2 Age.2 Size.3 Age.3 Size.4 Age.4 Size.5 Age.5
    #  <chr>       <int> <int>  <int> <int>  <int> <int>  <int> <int>  <int> <int>
    #1 ABC            11    16     79    57     70     2     80     6     91    24
    #2 BCD            67    81     63    77     48    73     52   100     49    76
    

    Both the solutions were @Duck's Duck's Profile URL and @akrun's Akrun's Profile URL brainchild. Thanks a tonne to them.

    0 讨论(0)
提交回复
热议问题