Отключение кадра данных в R

У меня есть следующее data.frame:

df <- data.frame(id=c(1,2,3), 
                 first.date=as.Date(c("2014-01-01", "2014-03-01", "2014-06-01")), 
                 second.date=as.Date(c("2015-01-01", "2015-03-01", "2015-06-1")),
                 third.date=as.Date(c("2016-01-01", "2017-03-01", "2018-06-1")),
                 fourth.date=as.Date(c("2017-01-01", "2018-03-01", "2019-06-1")))

> df

  id first.date second.date third.date fourth.date
1  1 2014-01-01  2015-01-01 2016-01-01  2017-01-01
2  2 2014-03-01  2015-03-01 2017-03-01  2018-03-01
3  3 2014-06-01  2015-06-01 2018-06-01  2019-06-01

Каждая строка представляет три промежутка времени; то есть промежуток времени между first.date и second.date, second.date и third.date и third.date и fourth.date соответственно.

Я хотел бы, за неимением лучшего слова, разложить фреймворк данных, чтобы вместо этого получить это:

  id  StartDate    EndDate
1  1 2014-01-01 2015-01-01
2  1 2015-01-01 2016-01-01
3  1 2016-01-01 2017-01-01
4  2 2014-03-01 2015-03-01
5  2 2015-03-01 2017-03-01
6  2 2017-03-01 2018-03-01
7  3 2014-06-01 2015-06-01
8  3 2015-06-01 2018-06-01
9  3 2018-06-01 2019-06-01

Я поигрался с функцией unnest из пакета tidyr, но пришел к выводу, что не думаю, что это то, что мне действительно нужно.

Какие-либо предложения?


person Morten Nielsen    schedule 07.01.2016    source источник


Ответы (2)


Вы можете попробовать tidyr/dplyr следующим образом:

library(tidyr)
library(dplyr)
df %>% gather(DateType, StartDate, -id) %>% select(-DateType) %>% arrange(id) %>% group_by(id) %>% mutate(EndDate = lead(StartDate))

Вы можете удалить последнюю строку в каждой группе идентификаторов, добавив:

%>% slice(-4)

К вышеуказанному трубопроводу.

person Gopala    schedule 07.01.2016
comment
Спасибо. Как раз то, что я искал. - person Morten Nielsen; 08.01.2016

Мы можем использовать data.table. Мы преобразуем «data.frame» в «data.table» (setDT(df)), затем melt набор данных в формате long, используем shift с type='lead', сгруппированными по «id», а затем удаляем NA элементы.

library(data.table)
na.omit(melt(setDT(df), id.var='id')[, shift(value,0:1, type='lead') , id])
#   id         V1         V2
#1:  1 2014-01-01 2015-01-01
#2:  1 2015-01-01 2016-01-01
#3:  1 2016-01-01 2017-01-01
#4:  2 2014-03-01 2015-03-01
#5:  2 2015-03-01 2017-03-01
#6:  2 2017-03-01 2018-03-01
#7:  3 2014-06-01 2015-06-01
#8:  3 2015-06-01 2018-06-01
#9:  3 2018-06-01 2019-06-01

Имена столбцов можно изменить с помощью setnames или ранее на шаге shift.

person akrun    schedule 07.01.2016
comment
Оцените и это предложение. Я не смог перевести его для использования с моими фактическими данными, но это больше связано с моими навыками R, чем с качеством предложения. - person Morten Nielsen; 08.01.2016