Я хочу резюмировать перемещения (между городами) на основе уникального идентификационного номера. Пример фрейма данных с двумя уникальными идентификаторами:

  year ID city   adress
1 2013  1    B adress_1
2 2014  1    B adress_1
3 2015  1    A adress_2
4 2016  1    A adress_2
5 2013  2    B adress_3
6 2014  2    B adress_3
7 2015  2    C adress_4
8 2016  2    C adress_4

Ниже я привел пример кода. Резюме верны, за исключением одного. Если, например, обнаружено перемещение между городом B и городом A, я хочу, чтобы результат перемещения был обнаружен из города B в город A (и количество раз, когда 1 = видели один раз во фрейме данных). Однако из-за свойств итоговой функции (и тенденции сохранять вывод в алфавитном порядке) я получаю следующий вывод

tmp <- df %>% group_by(ID, city, adress) %>% summarize(numberofyears = n())

tmp <- tmp %>% 
  group_by(ID) %>% 
  #filter(n() >1) %>% 
  mutate(from = city[1], from_adres = adress[1], from_years = numberofyears[1],  to = city[2],
  to_adres = adress[2], to_years = numberofyears[2]) %>% 
  distinct(ID, .keep_all = TRUE) %>% select(-c(2:3))


# A tibble: 2 x 8
# Groups:   ID [2]
     ID numberofyears from  from_adres from_years to    to_adres to_years
  <dbl>         <int> <fct> <fct>           <int> <fct> <fct>       <int>
1     1             2 A     adress_2            2 B     adress_1        2
2     2             2 B     adress_3            2 C     adress_4        2

Это неверно, потому что мы знаем, что адрес_1 предшествует адресу_2. Подводя итоги переезда из города B в город C, я получаю правильные результаты.

Это очень маленькая деталь, но очень важная, как я пытался продемонстрировать. Любые предложения были бы очень признательны!

0
Liri 23 Окт 2018 в 16:01

2 ответа

Лучший ответ

Подобно @jyjek, но это позволяет сделать более одного хода для каждого идентификатора.

library(tidyverse)

df <- data.frame(year = rep(2013:2016, 2),
                 ID = rep(1:2, each = 4),
                 city = c("B", "B", "A", "A", "B", "B", "C", "C"),
                 address = rep(1:4, each = 2),
                 stringsAsFactors = FALSE)


df %>% 
  group_by(ID, city, address) %>% 
  #note the first and last year at the address
  summarise(startyear = min(year),
            endyear = max(year)) %>% 
  #sort by ID and year
  arrange(ID, startyear) %>% 
  group_by(ID) %>% 
  #grab the next address for each ID
  mutate(to = lead(city),
         to_address = lead(address),
         to_years = lead(endyear) - lead(startyear) + 1,
         from_years = endyear - startyear + 1) %>% 
  #exclude the last row of each ID, since there's no next address being moved to
  filter(!is.na(to)) %>% 
  select(ID, from = city, from_address = address, from_years, to, to_address, to_years)
1
Jordo82 23 Окт 2018 в 13:23

Так?

 library(tidyverse)
    df<-read.table(text=" year ID city   adress
                1 2013  1    B adress_1
                2 2014  1    B adress_1
                3 2015  1    A adress_2
                4 2016  1    A adress_2
                5 2013  2    B adress_3
                6 2014  2    B adress_3
                7 2015  2    C adress_4
                8 2016  2    C adress_4",header=T)
    df%>%
       group_by(ID, city, adress)%>%
       summarize(numberofyears = n())%>%
       mutate(id=parse_number(adress))%>%
       group_by(ID,id)%>%
       arrange(id)%>%
       ungroup()%>%
       select(-id)%>%
       group_by(ID)%>%
       mutate(from=first(city), from_adres = first(adress),
              from_years = first(numberofyears),to=last(city),
              to_adres = last(adress),to_years=last(numberofyears))%>%
       distinct(ID, .keep_all = TRUE)%>%
       select(-c(2:3))
    # A tibble: 2 x 8
    # Groups:   ID [2]
         ID numberofyears from  from_adres from_years to    to_adres to_years
      <int>         <int> <fct> <fct>           <int> <fct> <fct>       <int>
    1     1             2 B     adress_1            2 A     adress_2        2
    2     2             2 B     adress_3            2 C     adress_4        2
1
jyjek 23 Окт 2018 в 13:09
52949780