R: Определить начальное условие для непрерывного значения - PullRequest
1 голос
/ 06 августа 2020

Я пытаюсь настроить две новые переменные для включения в существующий data.frame, который должен быть текущим значением, начинающимся с 1 (0), если выполняется условие относительно идентификаторов в data.frame. Итак, data.frame имеет аналогичную структуру:

ID   Var1
1     0
1     2 
1     5
1     12
2     0
2     2 
2     NA
2     11

, и я хочу получить:

ID  Var1   start   stop
1    0       0      0
1    2       0      1
1    5       1      2
1    12      2      3
2    0       0      0
2    2       0      1
2    NA      1      2
2    11      2      3

Start должно быть текущим значением, начиная с одного раза Var1 > 0 для первый раз и остановка должны действовать одинаково. Начальное значение Start должно быть 0, а начальное значение stop должно быть 1. Он должен продолжить работу, если Var1 снова принимает NA или 0 в течение data.frame. Я пробовал сделать следующее:

df %>%
  group_by(ID) %>%
  mutate(stop = ifelse(Var1 > 0, 
  0:nrow(df), 0))

Но возвращаемая им переменная начинается не с 0, а с номера строки, в которой сначала выполняется условие.

Ответы [ 2 ]

2 голосов
/ 06 августа 2020

Вот базовая опция R с использованием ave + replace

transform(df,
  Start = ave(ave(replace(Var1, is.na(Var1), 0) > 0, ID, FUN = cumsum) > 0, ID, FUN = function(x) cumsum(c(0, x))[-(length(x) + 1)]),
  Stop = ave(ave(replace(Var1, is.na(Var1), 0) > 0, ID, FUN = cumsum) > 0, ID, FUN = cumsum)
)

или

transform(df,
  Start = ave(ave(ave(replace(Var1, is.na(Var1), 0) > 0, ID, FUN = cumsum), ID, FUN = cumsum) > 1, ID, FUN = cumsum),
  Stop = ave(ave(replace(Var1, is.na(Var1), 0) > 0, ID, FUN = cumsum) > 0, ID, FUN = cumsum)
)

, что дает

  ID Var1 Start Stop
1  1    0     0    0
2  1    2     0    1
3  1    5     1    2
4  1   12     2    3
5  2    0     0    0
6  2    2     0    1
7  2   NA     1    2
8  2   11     2    3
2 голосов
/ 06 августа 2020

Извините, я не говорю на dplyr, но вы можете легко это адаптировать, поскольку data.table используется только для группировки.

DF <- read.table(text = "ID   Var1
1     0
1     2 
1     5
1     12
2     0
2     2 
2     NA
2     11", header = TRUE)

foo <- function(x) {
  #quantify leading zeros:
  x[is.na(x)] <- 0
  lead0 <- cumsum(x > 0) 
  nlead0 <- sum(lead0 == 0)
  
  #create result using sequence:
  list(c(rep.int(0, nlead0), sequence(length(x) - nlead0) - 1),
       c(rep.int(0, nlead0), sequence(length(x) - nlead0)))
}

library(data.table)
setDT(DF)
DF[, c("start", "stop") := foo(Var1), by = ID]
#   ID Var1 start stop
#1:  1    0     0    0
#2:  1    2     0    1
#3:  1    5     1    2
#4:  1   12     2    3
#5:  2    0     0    0
#6:  2    2     0    1
#7:  2   NA     1    2
#8:  2   11     2    3
...