R:Count每天每个ID区分一个变量的个数
R:Count daily number of a variable distinguish per ID
之前也问过类似的问题(),这次也想计算v的个数distinguish per天和每个ID,但是现在"distinguish"不仅意味着一天不同v
,而且意味着不同v
今天和以后的日子。
比如第二天有一个v1
,而且前一天也有,我们就不算第二天的v1。
ID1:
第 1 天:v1/v2 -----> 第 1 天 2
第 2 天:v1/v3 -----> 第 2 天 1 个
第 3 天:v3 -----> 第 3 天为 0
ID2
第 1 天:v4 -----> 第 1 天 1
第 2 天:v5/v4/v1 -----> 第 2 天 2
第 3 天:v3/v4 -----> 第 3 天 1 个
这是我的数据:
ID Day v
ID1 1 v1
ID1 1 v1
ID1 1 v2
ID1 2 v1
ID1 2 v3
ID1 3 v3
ID1 3 v3
ID1 3 v3
ID2 1 v4
ID2 2 v5
ID2 2 v5
ID2 2 v4
ID2 2 v1
ID2 3 v3
ID2 3 v4
根据我上面的数据,我想得到如下结果:
ID Day v daily_v_distinguish_ID
ID1 1 v1 2
ID1 1 v1 NA
ID1 1 v2 NA
ID1 2 v1 1
ID1 2 v3 NA
ID1 3 v3 0
ID1 3 v3 NA
ID1 3 v3 NA
ID2 1 v4 1
ID2 2 v5 2
ID2 2 v5 NA
ID2 2 v4 NA
ID2 2 v1 NA
ID2 3 v3 1
ID2 3 v4 NA
如果我们使用setDT(df1)[, daily_v_ID := c(uniqueN(v), rep(NA, .N-1)), by = .(ID, Day)]
,我们没有将这一天的v
与前几天进行比较。
我们可以使用 data.table
来创建 'daily_v_distinguish_ID'。将 'data.frame' 转换为 'data.table' (setDT(df1)
),按 'ID' 分组,我们根据 'v' 中不是 duplicated
的元素创建逻辑索引.在下一步中,我们按 'ID' 和 'Day' 列分组,得到 'indx' 的 sum
并与 'NA' 连接以填充其余元素每个组并分配 (:=
即 'daily_v_distinguish_ID'.
library(data.table)
setDT(df1)[, indx:=!duplicated(v) ,.(ID)
][, daily_v_distinguish_ID:= c(sum(indx),rep(NA, .N-1)) , .(ID, Day)
][,indx:=NULL]
df1
# ID Day v daily_v_distinguish_ID
# 1: ID1 1 v1 2
# 2: ID1 1 v1 NA
# 3: ID1 1 v2 NA
# 4: ID1 2 v1 1
# 5: ID1 2 v3 NA
# 6: ID1 3 v3 0
# 7: ID1 3 v3 NA
# 8: ID1 3 v3 NA
# 9: ID2 1 v4 1
#10: ID2 2 v5 2
#11: ID2 2 v5 NA
#12: ID2 2 v4 NA
#13: ID2 2 v1 NA
#14: ID2 3 v3 1
#15: ID2 3 v4 NA
使用 dplyr
的类似选项是
library(dplyr)
df1 %>%
group_by(ID) %>%
mutate(ind=!duplicated(v)) %>%
group_by(Day, add=TRUE)%>%
mutate(daily_v_distinguish_ID=c(sum(ind), rep(NA, n()-1))) %>%
select(-ind)
或使用 base R
中的 ave
with(df1, ave(!duplicated(df1[-2]), ID, Day, FUN=function(x)
c(sum(x), rep(NA, length(x)-1))))
#[1] 2 NA NA 1 NA 0 NA NA 1 2 NA NA NA 1 NA
数据
df1 <- structure(list(ID = c("ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
"ID1", "ID1", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2"
), Day = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 1L, 2L, 2L, 2L, 2L,
3L, 3L), v = c("v1", "v1", "v2", "v1", "v3", "v3", "v3", "v3",
"v4", "v5", "v5", "v4", "v1", "v3", "v4")), .Names = c("ID",
"Day", "v"), class = "data.frame", row.names = c(NA, -15L))
之前也问过类似的问题(v
,而且意味着不同v
今天和以后的日子。
比如第二天有一个v1
,而且前一天也有,我们就不算第二天的v1。
ID1:
第 1 天:v1/v2 -----> 第 1 天 2
第 2 天:v1/v3 -----> 第 2 天 1 个
第 3 天:v3 -----> 第 3 天为 0
ID2
第 1 天:v4 -----> 第 1 天 1
第 2 天:v5/v4/v1 -----> 第 2 天 2
第 3 天:v3/v4 -----> 第 3 天 1 个
这是我的数据:
ID Day v
ID1 1 v1
ID1 1 v1
ID1 1 v2
ID1 2 v1
ID1 2 v3
ID1 3 v3
ID1 3 v3
ID1 3 v3
ID2 1 v4
ID2 2 v5
ID2 2 v5
ID2 2 v4
ID2 2 v1
ID2 3 v3
ID2 3 v4
根据我上面的数据,我想得到如下结果:
ID Day v daily_v_distinguish_ID
ID1 1 v1 2
ID1 1 v1 NA
ID1 1 v2 NA
ID1 2 v1 1
ID1 2 v3 NA
ID1 3 v3 0
ID1 3 v3 NA
ID1 3 v3 NA
ID2 1 v4 1
ID2 2 v5 2
ID2 2 v5 NA
ID2 2 v4 NA
ID2 2 v1 NA
ID2 3 v3 1
ID2 3 v4 NA
如果我们使用setDT(df1)[, daily_v_ID := c(uniqueN(v), rep(NA, .N-1)), by = .(ID, Day)]
,我们没有将这一天的v
与前几天进行比较。
我们可以使用 data.table
来创建 'daily_v_distinguish_ID'。将 'data.frame' 转换为 'data.table' (setDT(df1)
),按 'ID' 分组,我们根据 'v' 中不是 duplicated
的元素创建逻辑索引.在下一步中,我们按 'ID' 和 'Day' 列分组,得到 'indx' 的 sum
并与 'NA' 连接以填充其余元素每个组并分配 (:=
即 'daily_v_distinguish_ID'.
library(data.table)
setDT(df1)[, indx:=!duplicated(v) ,.(ID)
][, daily_v_distinguish_ID:= c(sum(indx),rep(NA, .N-1)) , .(ID, Day)
][,indx:=NULL]
df1
# ID Day v daily_v_distinguish_ID
# 1: ID1 1 v1 2
# 2: ID1 1 v1 NA
# 3: ID1 1 v2 NA
# 4: ID1 2 v1 1
# 5: ID1 2 v3 NA
# 6: ID1 3 v3 0
# 7: ID1 3 v3 NA
# 8: ID1 3 v3 NA
# 9: ID2 1 v4 1
#10: ID2 2 v5 2
#11: ID2 2 v5 NA
#12: ID2 2 v4 NA
#13: ID2 2 v1 NA
#14: ID2 3 v3 1
#15: ID2 3 v4 NA
使用 dplyr
的类似选项是
library(dplyr)
df1 %>%
group_by(ID) %>%
mutate(ind=!duplicated(v)) %>%
group_by(Day, add=TRUE)%>%
mutate(daily_v_distinguish_ID=c(sum(ind), rep(NA, n()-1))) %>%
select(-ind)
或使用 base R
ave
with(df1, ave(!duplicated(df1[-2]), ID, Day, FUN=function(x)
c(sum(x), rep(NA, length(x)-1))))
#[1] 2 NA NA 1 NA 0 NA NA 1 2 NA NA NA 1 NA
数据
df1 <- structure(list(ID = c("ID1", "ID1", "ID1", "ID1", "ID1", "ID1",
"ID1", "ID1", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2", "ID2"
), Day = c(1L, 1L, 1L, 2L, 2L, 3L, 3L, 3L, 1L, 2L, 2L, 2L, 2L,
3L, 3L), v = c("v1", "v1", "v2", "v1", "v3", "v3", "v3", "v3",
"v4", "v5", "v5", "v4", "v1", "v3", "v4")), .Names = c("ID",
"Day", "v"), class = "data.frame", row.names = c(NA, -15L))