Подмножество фрейма данных и замена столбца на основе условия - PullRequest
0 голосов
/ 29 апреля 2018

Я работаю над фреймом данных с тремя столбцами, помеченными как 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 для каждого id, пока оно не станет больше или равно соответствующему значению time2 для этого id.

  2. Замените ячейки в time1, где суммы заканчиваются соответствующими значениями time2 для каждого id.

  3. Столбец time2 должен быть заменен новым столбцом, помеченным status, который состоит из 0 и 1. То есть status принимает 1 для незамещенных значений time1 и 0 для всех замененных значений time1.

В общем, я ожидаю увидеть что-то вроде этого:

df <-
  structure(
    list(
      id = c(1L, 1L, 1L, 1L, 2L, 3L, 3L, 3L, 4L, 4L, 4L),
      time1 = c(12L, 5L, 3L, 23, 22L, 17L, 5L, 25L, 5L, 15L, 24L),
      status=c(1L,1L,1L,0L,0L,1L,1L,0L,1L,1L,0L)
    ),
    .Names = c("id", "time1","status"),
    class = "data.frame",
    row.names = c(NA,-11L)
  )

Я очень ценю любую помощь в этом.

1 Ответ

0 голосов
/ 29 апреля 2018

Мы можем сделать следующее:

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) < time2 с 1, еще с 0; мы заменяем time1 записей на time2 записей, если status == 1. Наконец, нам нужно удалить лишние status = 0 строки; для этого мы перегруппируем по id и status, последовательно пронумеровывая строки, и оставляем только одну строку для status = 0 на id.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...