计算每个 ID 的访问次数 (cumsum),同时忽略 NA 和 0
Count visits (cumsum) per ID while ignoring NA's and 0's
我有以下 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))
如何在忽略 NA 或 0 的同时,根据 'Attendance' 列值,在 'Visit' 列中每次出现 ID(累计)?
我试过像这样的 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 函数计算访问次数,然后 合并 ,但我确信存在最简单的方法
我们可以使用data.table
。将 'data.frame' 转换为 'data.table' (setDT(df)
),按 'ID' 分组,将 i
指定为逻辑向量,对于 [ 中的非 NA 元素为真=26=],分配 (:=
) 'Attendance' 的 'rowid' 作为 'Visit' 列。然后,将'Visit'中的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))
library(dplyr)
df %>%
group_by(ID) %>%
mutate(Visit = if_else(is.na(Attendance), 0, cumsum(if_else(is.na(Attendance), 0, 1))))
我有以下 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))
如何在忽略 NA 或 0 的同时,根据 'Attendance' 列值,在 'Visit' 列中每次出现 ID(累计)?
我试过像这样的 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 函数计算访问次数,然后 合并 ,但我确信存在最简单的方法
我们可以使用data.table
。将 'data.frame' 转换为 'data.table' (setDT(df)
),按 'ID' 分组,将 i
指定为逻辑向量,对于 [ 中的非 NA 元素为真=26=],分配 (:=
) 'Attendance' 的 'rowid' 作为 'Visit' 列。然后,将'Visit'中的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))
library(dplyr)
df %>%
group_by(ID) %>%
mutate(Visit = if_else(is.na(Attendance), 0, cumsum(if_else(is.na(Attendance), 0, 1))))