Подсчет посещений (cumsum) по идентификатору, игнорируя NA и 0 - PullRequest
0 голосов
/ 06 июня 2018

У меня есть следующий df:

df <- data.frame(ID = c(1,1,2,2,2,3,3,3,3),
                 Attendance = c(1, 1, NA, 1,1, NA, 1, NA, 1 ))

И я хочу этот:

df <- data.frame(ID = c(1,1,2,2,2,3,3,3,3),
                 Attendance = c(1, 1, NA, 1,1, NA, 1, NA, 1),
                 Visit = c(1,2,0,1,2,0,1,0,2))

Как я могу рассчитывать каждый раз (cumsum) идентификатор появляется в «Посещение»столбец, основанный на значении столбца «Посещаемость» при игнорировании NA или 0?

Я пробовал что-то с ave функцией, подобной этой, но безуспешно:

df$Visit <- ifelse(!is.na(df$ID), (ave(df$ID, df$ID, FUN=cumsum))/df$ID, 0)

Я добился результата, создав вспомогательный df с помощью:

aux <- df[complete.cases(df$Attendance),] 

Подсчет посещений с помощью функции Ave и затем слияние , но я уверен, что существуетсамый простой способ

Ответы [ 2 ]

0 голосов
/ 06 июня 2018
library(dplyr)
df %>%
    group_by(ID) %>%
    mutate(Visit = if_else(is.na(Attendance), 0, cumsum(if_else(is.na(Attendance), 0, 1))))
0 голосов
/ 06 июня 2018

Мы можем использовать data.table.преобразуйте файл «data.frame» в «data.table» (setDT(df)), сгруппированный по «ID», укажите i в качестве логического вектора, который имеет значение «ИСТИНА» для элементов без NA в «Посещаемости», назначьте (:=) «rowid» «Посещаемости» в столбце «Посещение».Затем замените NA в «Визите» на 0

library(data.table)
setDT(df)[!is.na(Attendance), Visit := rowidv(Attendance), 
                   ID][is.na(Visit), Visit := 0]
df
#   ID Attendance Visit
#1:  1          1     1
#2:  1          1     2
#3:  2         NA     0
#4:  2          1     1
#5:  2          1     2
#6:  3         NA     0
#7:  3          1     1
#8:  3         NA     0
#9:  3          1     2

. Или, если мы используем ave, создайте индекс для строк, не являющихся NA, и затем используйте ave для этих строк.строки

i1 <- !is.na(df$Attendance)
df$Visit <- 0
df$Visit[i1] <- with(df[i1, ], ave(Attendance, ID, FUN = cumsum))
...