Как сдвинуть значение с помощью вложенного оператора ifelse? - PullRequest
2 голосов
/ 29 мая 2019

мой код

re$p_RID <- ifelse((re$group_UID & re$Amount_type=='Draw'),
                           shift(re$id), 'NA')

после запуска кода мой фрейм данных выглядит следующим образом:

id  user_id  Amount_type group_UID p_RID
30    11        Non        1        NA
31    11        Draw       1        30
54    5         Non        2        NA
322   5         Draw       2        54
21    5         Draw       2        322
13    5         Non        2        NA
2445  5         Draw       2        13
111   44        Non        3        NA
287   44        Draw       3        111

Я хотел бы использовать идентификатор в первом появлении для amount_type of Non valueдля каждого столбца p_RID. (в пределах одного и того же group_UID, если существует многократное вхождение Non-value, обрабатывайте каждое из них как первое вхождение) Результат должен выглядеть следующим образом:

id  user_id  Amount_type group_UID p_RID
30    11        Non        1        NA
31    11        Draw       1        30
54    5         Non        2        NA
322   5         Draw       2        54
21    5         Draw       2        54 <- this is where I don't know how to edit
13    5         Non        2        NA
2445  5         Draw       2        13
111   44        Non        3        NA
287   44        Draw       3        111

1 Ответ

0 голосов
/ 29 мая 2019

Использование dplyr в одну сторону - group_by group_UID и вхождение значения "Non" и присвоение NA первой строке и первому id в каждой группе в противном случае.

library(dplyr)

df %>%
  group_by(group_UID, group = cumsum(Amount_type == "Non")) %>%
  mutate(p_RID = ifelse(row_number() == 1, NA, id[1L])) %>%
  ungroup() %>%
  select(-group)


#    id user_id Amount_type group_UID  p_RID
#   <int>   <int> <fct>           <int> <int>
#1    30      11 Non                 1    NA
#2    31      11 Draw                1    30
#3    54       5 Non                 2    NA
#4   322       5 Draw                2    54
#5    21       5 Draw                2    54
#6    13       5 Non                 2    NA
#7  2445       5 Draw                2    13
#8   111      44 Non                 3    NA
#9   287      44 Draw                3   111

Другой способ будет

df %>%
  group_by(group_UID, group = cumsum(Amount_type == "Non")) %>%
  mutate(p_RID = ifelse(Amount_type == "Non", NA, first(id))) %>%
  ungroup() %>%
  select(-group)

Мы также можем использовать базу R ave здесь

with(df, ave(id, group_UID, cumsum(Amount_type == "Non"), FUN = function(x) 
    ifelse(seq_along(x) == 1, NA, x[1L])))

#[1]  NA  30  NA  54  54  NA  13  NA 111
...