如何在嵌套的 ifelse 语句中移动值?

How to shift value with inside nested ifelse statement?

我的代码

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

我想在每个 p_RID 列的非值 amount_type 上第一次出现时使用 id。(在同一个 group_UID 中,如果多次出现非值,则将每一个都视为第一次出现)结果应该是这样的:

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

使用 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)

这里我们也可以使用base 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