Нумерация строк в порядке по ID - PullRequest
1 голос
/ 31 мая 2019

Извините, если этот пост плохо организован, переполнение стека в первый раз ...

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

enter image description here]

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

enter image description here]

Ответы [ 3 ]

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

Один из вариантов - создать новую групповую переменную, когда разница между year больше 1, и создать последовательность в каждой группе, используя row_number().

library(dplyr)
df %>%
  group_by(ID, group = cumsum(c(1, diff(Year) > 1))) %>%
  mutate(order = row_number()) %>%
  ungroup() %>%
  select(-group)

#    ID     Year order
#   <fct>  <int> <int>
# 1  A      2007     1
# 2  A      2008     2
# 3  A      2009     3
# 4  A      2013     1
# 5  A      2014     2
# 6  A      2015     3
# 7  A      2016     4
# 8  B      2010     1
# 9  B      2012     1
#10  B      2013     2

Используя базу R ave, это будет

as.integer(with(df, ave(ID, ID, cumsum(c(1, diff(Year) > 1)), FUN = seq_along)))
#[1] 1 2 3 1 2 3 4 1 1 2

данные

df <- data.frame(ID = c(rep("A", 7), rep("B", 3)),
       Year = c(2007:2009, 2013:2016, 2010, 2012, 2013), stringsAsFactors = FALSE)
1 голос
/ 31 мая 2019

A data.table опция:

library(data.table)
setDT(df)
df[, jump := Year - shift(Year) - 1, by = ID
   ][is.na(jump), jump := 0
     ][, order := seq_len(.N), by = .(ID, cumsum(jump))]

#     ID Year jump order
#  1:  A 2007    0     1
#  2:  A 2008    0     2
#  3:  A 2009    0     3
#  4:  A 2013    3     1
#  5:  A 2014    0     2
#  6:  A 2015    0     3
#  7:  A 2016    0     4
#  8:  B 2010    0     1
#  9:  B 2012    1     1
# 10:  B 2013    0     2

Или использование data.table::nafill() доступно в data.table v1.12.3 (все еще в разработке):

df[, jump := nafill(Year - shift(Year) - 1, fill = 0), by = ID
   ][, order := seq_len(.N), by = .(ID, cumsum(jump))]
0 голосов
/ 31 мая 2019

Мы можем взять разницу 'Year' и lag от 'Year', получить кумулятивную сумму, использовать ее в group_by вместе с 'ID' и создать order как row_number()

library(dplyr)
df %>% 
  group_by(ID, grp = cumsum(Year - lag(Year, default = Year[1]) > 1)) %>%
  mutate(order = row_number()) %>% 
  ungroup %>%
  select(-grp)
# A tibble: 10 x 3
#   ID     Year order
#   <chr> <dbl> <int>
# 1 A      2007     1
# 2 A      2008     2
# 3 A      2009     3
# 4 A      2013     1
# 5 A      2014     2
# 6 A      2015     3
# 7 A      2016     4
# 8 B      2010     1
# 9 B      2012     1
#10 B      2013     2

данные

df <- structure(list(ID = c("A", "A", "A", "A", "A", "A", "A", "B", 
"B", "B"), Year = c(2007, 2008, 2009, 2013, 2014, 2015, 2016, 
2010, 2012, 2013)), class = "data.frame", row.names = c(NA, -10L
))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...