Как изменить таблицу R с длинной на широкую с датами? - PullRequest
0 голосов
/ 13 января 2020

У меня есть данные о событиях покупки и возрасте человека.

Name     Item     Date
PersonA   Apple    1/1/14
PersonA   Banana   1/1/13
PersonA   Pear     1/1/12
PersonB   Orange   1/1/15
PersonC   Kiwi     1/1/17
PersonC   Grapes   1/1/12
PersonD   Lemon    1/1/16

Я хочу переставить его с длинного на широкий, но, сохраняя даты для каждого из событий покупки, т. Е.

Name     Item.x    Date.x     Item.y     Date.y     Item.z     Item.z
PersonA   Pear      1/1/12     Banana     1/1/13     Apple      1/1/14
PersonB   Orange    1/1/15     NA         NA         NA         NA       
PersonC   Grapes    1/1/12     Kiwi       1/1/17     NA         NA  
PersonD   Lemon     1/1/16

, я вижу много вопросов об общем c long широко, но не уверен, как вывести его в широкоформатный формат, когда задействованы два столбца (элемент плюс дата).

Ответы [ 2 ]

1 голос
/ 13 января 2020

Мы можем использовать pivot_wider

library(dplyr)
library(tidyr)
library(lubridate)
df1 %>%
    arrange(Name, mdy(Date)) %>%
    group_by(Name) %>% 
    mutate(rn = c('x', 'y', 'z')[row_number()]) %>% 
    ungroup %>%
    pivot_wider(names_from = rn, values_from = c(Item, Date), names_sep=".")%>% 
    select(Name, ends_with('x'), ends_with('y'), ends_with('z'))
# A tibble: 4 x 7
#  Name    Item.x Date.x Item.y Date.y Item.z Date.z
#  <chr>   <chr>  <chr>  <chr>  <chr>  <chr>  <chr> 
#1 PersonA Pear   1/1/12 Banana 1/1/13 Apple  1/1/14
#2 PersonB Orange 1/1/15 <NA>   <NA>   <NA>   <NA>  
#3 PersonC Grapes 1/1/12 Kiwi   1/1/17 <NA>   <NA>  
#4 PersonD Lemon  1/1/16 <NA>   <NA>   <NA>   <NA>  

данные

df1 <- structure(list(Name = c("PersonA", "PersonA", "PersonA", "PersonB", 
"PersonC", "PersonC", "PersonD"), Item = c("Apple", "Banana", 
"Pear", "Orange", "Kiwi", "Grapes", "Lemon"), Date = c("1/1/14", 
"1/1/13", "1/1/12", "1/1/15", "1/1/17", "1/1/12", "1/1/16")), 
class = "data.frame", row.names = c(NA, 
-7L))
0 голосов
/ 13 января 2020

в базе R вы можете сделать:

df2 <- transform(df1, time = ave(Item, Name, FUN = function(x)c("x", "y", "z")[seq(x)]))

reshape(df2, idvar = "Name", dir = "wide")

     Name Item.x Date.x Item.y Date.y Item.z Date.z
1 PersonA  Apple 1/1/14 Banana 1/1/13   Pear 1/1/12
4 PersonB Orange 1/1/15   <NA>   <NA>   <NA>   <NA>
5 PersonC   Kiwi 1/1/17 Grapes 1/1/12   <NA>   <NA>
7 PersonD  Lemon 1/1/16   <NA>   <NA>   <NA>   <NA>

, если вас не волнует x,y,z, вы можете сделать:

reshape(transform(df1,time = ave(Item,Name,FUN = seq_along)),idvar = "Name",dir="wide")

     Name Item.1 Date.1 Item.2 Date.2 Item.3 Date.3
1 PersonA  Apple 1/1/14 Banana 1/1/13   Pear 1/1/12
4 PersonB Orange 1/1/15   <NA>   <NA>   <NA>   <NA>
5 PersonC   Kiwi 1/1/17 Grapes 1/1/12   <NA>   <NA>
7 PersonD  Lemon 1/1/16   <NA>   <NA>   <NA>   <NA>
...