简体   繁体   中英

Is there a way to reshape data in R with 2 sets of measure variables

I want to reshape from wide to long Format, but I have 2 sets of measure of variable. Is it possible to use one melt to get FData2 below. I want to use one melt to achieve this. As I have alot of sets to change from wide to long.

Eg

id <- c(1,2,3,4,5,6,7,8,9,10)
Pepsi_Purchase <- c(3,4,5,6,7,8,2,2,3,NA)
Pepsi_Price <- c(NA,NA,4,6,7,8,8,9,6,7)
Coke_Purchase <- c(5,4,5,NA,7,8,2,NA,3,NA)
Coke_Price <- c(5,4,5,5,7,8,2,5,3,NA)

Data <- data.frame(id,Pepsi_Purchase,Coke_Purchase,Pepsi_Price,Coke_Price)
library(reshape2)

PC = melt(Data, id.vars = "id", measure.vars = ( c("Pepsi_Purchase", "Coke_Purchase")), variable.name = "Purvar" , value.name  = "Purchase" )
RC = melt(Data, id.vars = "id", measure.vars = ( c("Pepsi_Price", "Coke_Price")),variable.name = "PriVar" , value.name  = "Price" )

FData = cbind(PC,RC)
Fdata2 = FData[,c(1,2,5,3,6)]

Desired output

  id         Purvar      PriVar Purchase Price
1   1 Pepsi_Purchase Pepsi_Price        3    NA
2   2 Pepsi_Purchase Pepsi_Price        4    NA
3   3 Pepsi_Purchase Pepsi_Price        5     4
4   4 Pepsi_Purchase Pepsi_Price        6     6
5   5 Pepsi_Purchase Pepsi_Price        7     7
6   6 Pepsi_Purchase Pepsi_Price        8     8
7   7 Pepsi_Purchase Pepsi_Price        2     8
8   8 Pepsi_Purchase Pepsi_Price        2     9
9   9 Pepsi_Purchase Pepsi_Price        3     6
10 10 Pepsi_Purchase Pepsi_Price       NA     7
11  1  Coke_Purchase  Coke_Price        5     5
12  2  Coke_Purchase  Coke_Price        4     4
13  3  Coke_Purchase  Coke_Price        5     5
14  4  Coke_Purchase  Coke_Price       NA     5
15  5  Coke_Purchase  Coke_Price        7     7
16  6  Coke_Purchase  Coke_Price        8     8
17  7  Coke_Purchase  Coke_Price        2     2
18  8  Coke_Purchase  Coke_Price       NA     5
19  9  Coke_Purchase  Coke_Price        3     3
20 10  Coke_Purchase  Coke_Price       NA    NA

Can I generate FData2 with one melt?

Here's a way but I'd stick with two melt or its tidyverse equivalent

data.frame(lapply(split.default(Data, substring(names(Data), 1, 2)), stack))
#   id.values id.ind Pc.values Pc.ind Rc.values Rc.ind
#1          1     id         3    Pc1         5    Rc1
#2          2     id         4    Pc1         4    Rc1
#3          3     id         5    Pc1         5    Rc1
#4          4     id         6    Pc1        NA    Rc1
#5          5     id         7    Pc1         7    Rc1
#6          6     id         8    Pc1         8    Rc1
#7          7     id         2    Pc1         2    Rc1
#8          8     id         2    Pc1        NA    Rc1
#9          9     id         3    Pc1         3    Rc1
#10        10     id        NA    Pc1        NA    Rc1
#11         1     id        NA    Pc2         5    Rc2
#12         2     id        NA    Pc2         4    Rc2
#13         3     id         4    Pc2         5    Rc2
#14         4     id         6    Pc2         5    Rc2
#15         5     id         7    Pc2         7    Rc2
#16         6     id         8    Pc2         8    Rc2
#17         7     id         8    Pc2         2    Rc2
#18         8     id         9    Pc2         5    Rc2
#19         9     id         6    Pc2         3    Rc2
#20        10     id         7    Pc2        NA    Rc2

Consider tidyr::pivot_longer() . The 'Reshape2' package was replaced by 'tidyr' many years ago.

I've essentially combined Purvar & PriVar , since they appear redundant.

Data %>% 
  tidyr::pivot_longer(
    -id,
    names_to      = c("set", ".value"),              # This order is flipped, compared to the first SO submission.
    names_pattern = "(Pepsi|Coke)_(Purchase|Price)"
  ) %>% 
  dplyr::arrange(dplyr::desc(set), id)               # This line merely helps the visual comparison with the desired output above.

Result:

# A tibble: 20 x 4
      id set   Purchase Price
   <dbl> <chr>    <dbl> <dbl>
 1     1 Pepsi        3    NA
 2     2 Pepsi        4    NA
 3     3 Pepsi        5     4
 4     4 Pepsi        6     6
 5     5 Pepsi        7     7
 6     6 Pepsi        8     8
 7     7 Pepsi        2     8
 8     8 Pepsi        2     9
 9     9 Pepsi        3     6
10    10 Pepsi       NA     7
11     1 Coke         5     5
12     2 Coke         4     4
13     3 Coke         5     5
14     4 Coke        NA     5
15     5 Coke         7     7
16     6 Coke         8     8
17     7 Coke         2     2
18     8 Coke        NA     5
19     9 Coke         3     3
20    10 Coke        NA    NA

If you need FData2 exactly ( ie , the Purvar & Privar variables):

Data %>% 
  tidyr::pivot_longer(
    -id,
    names_to      = c("set", ".value"),
    names_pattern = "(Pepsi|Coke)_(Purchase|Price)"
  ) %>%
  dplyr::mutate(
    Purvar    = paste0(set, "_", "Purchase"),
    PriVar    = paste0(set, "_", "Price")
  )  %>% 
  dplyr::arrange(dplyr::desc(set), id)%>% 
  dplyr::select(id, Purvar, PriVar, Purchase, Price)
# A tibble: 20 x 5
      id Purvar         PriVar      Purchase Price
   <dbl> <chr>          <chr>          <dbl> <dbl>
 1     1 Pepsi_Purchase Pepsi_Price        3    NA
 2     2 Pepsi_Purchase Pepsi_Price        4    NA
 3     3 Pepsi_Purchase Pepsi_Price        5     4
 4     4 Pepsi_Purchase Pepsi_Price        6     6
 5     5 Pepsi_Purchase Pepsi_Price        7     7
 6     6 Pepsi_Purchase Pepsi_Price        8     8
 7     7 Pepsi_Purchase Pepsi_Price        2     8
 8     8 Pepsi_Purchase Pepsi_Price        2     9
 9     9 Pepsi_Purchase Pepsi_Price        3     6
10    10 Pepsi_Purchase Pepsi_Price       NA     7
11     1 Coke_Purchase  Coke_Price         5     5
12     2 Coke_Purchase  Coke_Price         4     4
13     3 Coke_Purchase  Coke_Price         5     5
14     4 Coke_Purchase  Coke_Price        NA     5
15     5 Coke_Purchase  Coke_Price         7     7
16     6 Coke_Purchase  Coke_Price         8     8
17     7 Coke_Purchase  Coke_Price         2     2
18     8 Coke_Purchase  Coke_Price        NA     5
19     9 Coke_Purchase  Coke_Price         3     3
20    10 Coke_Purchase  Coke_Price        NA    NA

Pivoting vignette

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM