我有以下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))
如何在“访问”列中根据“出勤”列值显示ID(每次出现(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 功能计算访问次数,然后合并,但我确信存在最简单的方法
答案 0 :(得分:1)
我们可以使用data.table
。转换&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df)
),按&#39; ID&#39;分组,将i
指定为逻辑向量,对于非参考文献中的非NA元素为TRUE,分配( :=
)&#39; rowid&#39;的出席情况&#39;作为&#39;访问&#39;柱。然后,在&#39;访问&#39;中替换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))
答案 1 :(得分:1)
library(dplyr)
df %>%
group_by(ID) %>%
mutate(Visit = if_else(is.na(Attendance), 0, cumsum(if_else(is.na(Attendance), 0, 1))))