R:计算每个ID区分变量的每日数

vel*_*ock 5 r count

这是我的数据:

ID        Date             v
ID1         1              v1
ID1         1              v1
ID1         1              v8
ID1         2              v5
ID1         2              v3
ID1         3              v3
ID2         1              v7
ID2         2              v15
ID2         2              v15
ID2         3              v3
Run Code Online (Sandbox Code Playgroud)

我想计算每天每个ID的v 分数.正如我上面的数据,我想得到如下结果:

ID        Date             v         daily_v_distinguish_ID
ID1         1              v1            2
ID1         1              v1            NA
ID1         1              v8            NA
ID1         2              v5            2
ID1         2              v3            NA
ID1         3              v3            1
ID2         1              v7            1
ID2         2              v15           1
ID2         2              v15           NA
ID2         3              v3            1
Run Code Online (Sandbox Code Playgroud)

怎么解决?提前谢谢你!

然后,如果我只想计算每个ID 的每日v(不是distingunish),如何更改代码?

预期结果:

ID        Date             v         daily_v_distinguish_ID    daily_v_ID
ID1         1              v1            2                       3
ID1         1              v1            NA                      3
ID1         1              v8            NA                      3
ID1         2              v5            2                       2
ID1         2              v3            NA                      2
ID1         3              v3            1                       1
ID2         1              v7            1                       1
ID2         2              v15           1                       2
ID2         2              v15           NA                      2
ID2         3              v3            1                       1
Run Code Online (Sandbox Code Playgroud)

akr*_*run 7

您可以尝试使用ie 的devel版本data.table.v1.9.5.安装devel版本的说明是here

library(data.table)#v1.9.5+
setDT(df1)[,  daily_v_ID:= ifelse((1:.N)==1L, uniqueN(v), NA) , by = .(ID, Date)]
Run Code Online (Sandbox Code Playgroud)

要么

setDT(df1)[,  daily_v_ID := c(uniqueN(v), rep(NA, .N-1)), by = .(ID, Date)]
Run Code Online (Sandbox Code Playgroud)

或者按照@David Arenburg的建议

indx <- setDT(df1)[, .(.I[1L], uniqueN(v)), by = .(ID, Date)] 
df1[indx$V1, daily_v_ID := indx$V2]
Run Code Online (Sandbox Code Playgroud)

或使用 dplyr

library(dplyr)
df1 %>% 
  group_by(ID,Date) %>%
  mutate(daily_v_ID= ifelse(row_number()==1, n_distinct(v), NA))
Run Code Online (Sandbox Code Playgroud)

或者 base R

df1$daily_v_ID <- with(df1, ave(as.numeric(factor(v)), Date,ID,
      FUN= function(x) NA^(seq_along(x)!=1)*length(unique(x))))
Run Code Online (Sandbox Code Playgroud)

更新

对于编辑过的帖子,我们通过获取length(v)或者在中data.table,我们可以使用创建变量('daily_v_ID').N

setDT(df1)[, c('daily_v_distinguish_ID', 'daily_v_ID'):= list( c(uniqueN(v),
                  rep(NA, .N-1)), .N), by = .(ID, Date)]
df1
#       ID Date   v daily_v_distinguish_ID daily_v_ID
#  1: ID1    1  v1                      2          3
#  2: ID1    1  v1                     NA          3
#  3: ID1    1  v8                     NA          3
#  4: ID1    2  v5                      2          2
#  5: ID1    2  v3                     NA          2
#  6: ID1    3  v3                      1          1
#  7: ID2    1  v7                      1          1
#  8: ID2    2 v15                      1          2
#  9: ID2    2 v15                     NA          2
# 10: ID2    3  v3                      1          1
Run Code Online (Sandbox Code Playgroud)

注意:uniqueNv1.9.5.中引入.对于早期版本,我们可以使用unique(length(v))

或使用 dplyr

df1 %>% 
    group_by(ID, Date) %>%
    mutate(daily_v_distinguish_ID = ifelse(row_number()==1,
                                        n_distinct(v), NA), 
           daily_v_ID =n())
Run Code Online (Sandbox Code Playgroud)