我有一个数据帧如下.它按列排序time.
输入 -
df = data.frame(time = 1:20,
grp = sort(rep(1:5,4)),
var1 = rep(c('A','B'),10)
)
head(df,10)
time grp var1
1 1 1 A
2 2 1 B
3 3 1 A
4 4 1 B
5 5 2 A
6 6 2 B
7 7 2 A
8 8 2 B
9 9 3 A
10 10 3 B
Run Code Online (Sandbox Code Playgroud)
我想创建另一个变量var2,它var1到目前为止计算不同的值,即直到time每个组的那个点grp.这与我使用时的情况略有不同n_distinct.
预期产量 -
time grp var1 var2
1 1 1 A 1
2 2 1 B 2
3 3 1 A 2
4 4 1 B 2
5 5 2 A 1
6 6 2 B 2
7 7 2 A 2
8 8 2 B 2
9 9 3 A 1
10 10 3 B 2
Run Code Online (Sandbox Code Playgroud)
我想为此创建一个函数cum_n_distinct并将其用作 -
d_out = df %>%
arrange(time) %>%
group_by(grp) %>%
mutate(var2 = cum_n_distinct(var1))
Run Code Online (Sandbox Code Playgroud)
dplyr解决方案,从@ akrun的回答启发-这种逻辑基本上是为每个组设置to的每个唯一值的第一个匹配项,然后将set设置var1为1rest ,然后在其上应用-0grpcumsum
df = df %>%
arrange(time) %>%
group_by(grp,var1) %>%
mutate(var_temp = ifelse(row_number()==1,1,0)) %>%
group_by(grp) %>%
mutate(var2 = cumsum(var_temp)) %>%
select(-var_temp)
head(df,10)
Source: local data frame [10 x 4]
Groups: grp
time grp var1 var2
1 1 1 A 1
2 2 1 B 2
3 3 1 A 2
4 4 1 B 2
5 5 2 A 1
6 6 2 B 2
7 7 2 A 2
8 8 2 B 2
9 9 3 A 1
10 10 3 B 2
Run Code Online (Sandbox Code Playgroud)
假设time已经按顺序排序,首先定义一个累积的不同函数:
dist_cum <- function(var)
sapply(seq_along(var), function(x) length(unique(head(var, x))))
Run Code Online (Sandbox Code Playgroud)
然后是ave用于创建组的基本解决方案(注意,假设var1是因子),然后将我们的函数应用于每个组:
transform(df, var2=ave(as.integer(var1), grp, FUN=dist_cum))
Run Code Online (Sandbox Code Playgroud)
一个data.table解决方案,基本上还是在做同样的事情:
library(data.table)
(data.table(df)[, var2:=dist_cum(var1), by=grp])
Run Code Online (Sandbox Code Playgroud)
而且dplyr,同样的事情:
library(dplyr)
df %>% group_by(grp) %>% mutate(var2=dist_cum(var1))
Run Code Online (Sandbox Code Playgroud)