Преобразование формата датафрейма в R: как с датами в годах (каждый идентификатор новой строки в год) - PullRequest
2 голосов
/ 29 апреля 2020

Мне нужно преобразовать мой фрейм данных из текущего в новый формат (см. Изображение или структуру ниже). Я понятия не имею, как я могу это сделать. Я хочу год для каждого идентификатора, начиная с 2013-2018 гг. (Поэтому у каждого идентификатора есть 6 строк, по одной на каждый год). Даты - это даты проживания по этому адресу (дата въезда) и когда они покинули этот адрес (дата окончания). Таким образом, каждый идентификатор и год дает почтовый индекс и город, в котором они жили. Место, в котором удостоверение личности проживало (для каждого года), должно быть, где они жили дольше всего в этом году. Я уже установил конечную дату 31-12-2018, если они все еще живут там (здесь показано с NA). Ниже картинка и первые 3 ряда. Надеюсь, вы, ребята, можете мне помочь!

Текущий формат:

  • ID (1, 1, 2)
  • ZIPCODE (1234AB, 5678CD, 9012EF)
  • ГОРОД (НЬЮ-ЙОРК, ЛА, МАЙАМИ)
  • ENTRY_DATE (2-1-2014, 13-3-2017, 10-11-2011)
  • END_DATE (13-5- 2017, 21-12-2018, 6-9-2017)

Новый формат:

  • ID (1, 1, 1, 1, 1, 1, 2 )
  • ГОД (2013, 2014, 2015, 2016, 2017, 2018, 2013)
  • ZIPCODE (NA, 1234AB, 1234AB, 1234AB, 5678CD, 5678CD, 9012EF)
  • ГОРОД (NA, NEWYORK, NEWYORK, NEWYORK, LA, LA, MIAMI)

    См. Ссылку ниже

1 Ответ

2 голосов
/ 30 апреля 2020

Вот один подход.

Сначала создайте интервалы дат для каждого местоположения от начальной до конечной даты. Используя map2 и unnest, вы создадите дополнительные строки для каждого года.

Поскольку вы sh добавили информацию о местоположении, где было наибольшее количество дней в этом календарном году, вы можете посмотреть с перекрытием между 2 интервалами: один интервал - календарный год, а второй интервал - от ENTRY_DATE до END_DATE. Для каждого года вы можете filter на max(WEEKS) (или для обеспечения одного адреса в год, упорядочить в порядке убывания по НЕДЕЛЯМ и slice(1) --- или с последним tidyr рассмотрим slice_max). Это сохранит строку, в которой между интервалами будет наибольшее количество недель продолжительности.

Финальный complete обеспечит наличие строк для всех лет между 2013-2018.

library(tidyverse)
library(lubridate)

df %>%
  mutate(ENTRY_END_INT = interval(ENTRY_DATE, END_DATE),
         YEAR = map2(year(ENTRY_DATE), year(END_DATE), seq)) %>%
  unnest(YEAR) %>%
  mutate(YEAR_INT = interval(as.Date(paste0(YEAR, '-01-01')), as.Date(paste0(YEAR, '-12-31'))),
         WEEKS = as.duration(intersect(ENTRY_END_INT, YEAR_INT))) %>%
  group_by(ID, YEAR) %>%
  arrange(desc(WEEKS)) %>%
  slice(1) %>%
  group_by(ID) %>%
  complete(YEAR = seq(2013, 2018, 1)) %>%
  arrange(ID, YEAR) %>%
  select(-c(ENTRY_DATE, END_DATE, ENTRY_END_INT, YEAR_INT, WEEKS))

Выход

# A tibble: 14 x 4
# Groups:   ID [2]
      ID  YEAR ZIPCODE CITY   
   <dbl> <dbl> <chr>   <chr>  
 1     1  2013 NA      NA     
 2     1  2014 1234AB  NEWYORK
 3     1  2015 1234AB  NEWYORK
 4     1  2016 1234AB  NEWYORK
 5     1  2017 5678CD  LA     
 6     1  2018 5678CD  LA     
 7     2  2011 9012EF  MIAMI  
 8     2  2012 9012EF  MIAMI  
 9     2  2013 9012EF  MIAMI  
10     2  2014 9012EF  MIAMI  
11     2  2015 9012EF  MIAMI  
12     2  2016 9012EF  MIAMI  
13     2  2017 9012EF  MIAMI  
14     2  2018 NA      NA    

Данные

df <- structure(list(ID = c(1, 1, 2), ZIPCODE = c("1234AB", "5678CD", 
"9012EF"), CITY = c("NEWYORK", "LA", "MIAMI"), ENTRY_DATE = structure(c(16072, 
17238, 15288), class = "Date"), END_DATE = structure(c(17299, 
17896, 17415), class = "Date")), class = "data.frame", row.names = c(NA, 
-3L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...