子集数据框并根据条件替换列

时间:2018-04-29 13:06:24

标签: r

我正在处理一个数据框,其中有三列标记为id,time1和time2。样本是:

df <-
  structure(
    list(
      id = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L),
      time1 = c(12L, 5L, 3L, 5L, 6L, 30L, 3L, 30L, 7L, 2L, 17L, 5L, 8L, 3L, 22L, 5L, 15L, 4L, 7L, 23L),
      time2=c(23L,23L,23L,23L,23L,22L,22L,22L,22L,22L,25L,25L,25L,25L,25L,24L,24L,24L,24L,24L)
    ),
    .Names = c("id", "time1","time2"),
    class = "data.frame",
    row.names = c(NA,-20L)
  )

我正在使用R,我正在尝试对此数据进行分组,并根据以下条件将列time2替换为新列:

  1. 对每个time1的{​​{1}}值求和,直到它大于或等于id的{​​{1}}的对应值。

  2. 将总结终止的time2中的单元格替换为每个id的相应time1值。

  3. time2将替换为标记为id的新列,其中包含time2status。也就是说,对于0的所有替换值,1status1的未替换值采用time1

  4. 总之,我希望看到这样的事情:

    0

    我非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

我们可以做到以下几点:

library(tidyverse);
df %>%
    group_by(id) %>%
    mutate(
        status = as.numeric(cumsum(time1) < time2),
        time1 = ifelse(status == 1, time1, time2)) %>%
    group_by(id, status) %>%
    mutate(n = 1:n()) %>%
    ungroup() %>%
    filter(status == 1 | (status == 0 & n == 1)) %>%
    select(-n, -time2)
## A tibble: 11 x 3
#      id time1 status
#   <int> <int>  <dbl>
# 1     1    12     1.
# 2     1     5     1.
# 3     1     3     1.
# 4     1    23     0.
# 5     2    22     0.
# 6     3    17     1.
# 7     3     5     1.
# 8     3    25     0.
# 9     4     5     1.
#10     4    15     1.
#11     4    24     0.

说明:我们按id对行进行分组,然后计算time1条目的累计总和,并标记cumsum(time1) < time21的行,否则为{{1 }};如果0,我们会将time1条目替换为time2个条目。最后,我们需要删除多余的status == 1行;为此,我们按status = 0id重新组合,连续编号行,并且statusstatus = 0只保留一行。