Как преобразовать данные из широкого в длинный формат, но с правильными датами - PullRequest
0 голосов
/ 07 мая 2019
ID  Date1        Date2       Date3        Value1  Value2  Value3
1   1/14/2019    4/14/2019   8/14/2019     123     122     143  
2   1/14/2019    4/14/2019   8/14/2019     111     116     119  

Мне нужно преобразовать приведенный выше кадр данных в приведенный ниже R

Ожидаемый вывод

ID   Date     Value
1    January  123   
1    April    122
1    August   143
2    January  111   
2    April    116
2    August   119

Что я пробовал:

library(reshape2)
long <- melt(wide, id.vars = "ID") 

, но это нене дает мне правильную продукцию в месяцах.

1 Ответ

2 голосов
/ 07 мая 2019

Использование старой доброй базы R reshape

cols <- grep("^Date", names(df))

df[cols] <- lapply(df[cols], function(x) format(as.Date(x, "%m/%d/%Y"), "%B"))

reshape(df, timevar = "ID", direction = "long", 
  varying = list(cols, grep("Value", names(df))), v.names = c("Date", "Value"))

#    ID    Date Value id
#1.1  1 January   123  1
#2.1  1 January   111  2
#1.2  2   April   122  1
#2.2  2   April   116  2
#1.3  3  August   143  1
#2.3  3  August   119  2

Мы также можем использовать data.table melt после выполнения шага lapply сверху

library(data.table)

melt(setDT(df), id="ID", measure=patterns("^Date", "^Value"),
               value.name=c("Date", "Value"))

Или делать все в одной цепочке, используя tidyverse

library(tidyverse)
library(lubridate)

df %>%
  gather(key, value, -ID) %>%
  group_by(group = sub("\\d+", "", key)) %>%
  select(-key) %>%
  mutate(row =row_number()) %>%
  spread(group, value) %>%
  mutate(Date = format(mdy(Date), "%B")) %>%
  select(-row)

#     ID Date    Value
#   <int> <chr>   <chr>
#1     1 January 123  
#2     1 April   122  
#3     1 August  143  
#4     2 January 111  
#5     2 April   116  
#6     2 August  119  
...