问题描述
cnpj | time2 | n_act_contracts |
---|---|---|
12 | -1 | 10 |
12 | 0 | 8 |
12 | 1 | 6 |
13 | -1 | 3 |
13 | 0 | 5 |
13 | 1 | 7 |
14 | 1 | 3 |
14 | 2 | 5 |
14 | 3 | 7 |
15 | 不适用 | 3 |
15 | 不适用 | 5 |
15 | 不适用 | 7 |
我想定义另一个变量,对于所有具有相同 cnpj 的观察,当变量 time2 等于 0 时,n_act_contracts 的值。
cnpj | time2 | n_act_contracts | zero_n_act_contracts |
---|---|---|---|
12 | -1 | 10 | 8 |
12 | 0 | 8 | 8 |
12 | 1 | 6 | 8 |
13 | -1 | 3 | 5 |
13 | 0 | 5 | 5 |
13 | 1 | 7 | 5 |
14 | 1 | 3 | 不适用 |
14 | 2 | 5 | 不适用 |
14 | 3 | 7 | 不适用 |
15 | 不适用 | 3 | 不适用 |
15 | 不适用 | 5 | 不适用 |
15 | 不适用 | 7 | 不适用 |
我一直在使用以下几行代码来做这件事,但我需要让它更有效率。
data <- data %>%
group_by(cnpj) %>%
mutate(
zero_n_act_contracts = ifelse(time2 == 0,n_act_contracts,-1000),zero_n_act_contracts = max(zero_n_act_contracts,na.rm = TRUE),zero_n_act_contracts = ifelse(zero_n_act_contracts == -1000,NA,zero_n_act_contracts))
obs:我已经尝试用 dplyr: "if_else" 替换 base "ifelse",但我的代码运行时间更长。
解决方法
我们可以使用
library(dplyr)
data %>%
group_by(cnpj) %>%
mutate(zero_n_act_contracts = n_act_contracts[time2 == 0][1]) %>%
ungroup
-输出
# A tibble: 12 x 4
# cnpj time2 n_act_contracts zero_n_act_contracts
# <int> <int> <int> <int>
# 1 12 -1 10 8
# 2 12 0 8 8
# 3 12 1 6 8
# 4 13 -1 3 5
# 5 13 0 5 5
# 6 13 1 7 5
# 7 14 1 3 NA
# 8 14 2 5 NA
# 9 14 3 7 NA
#10 15 NA 3 NA
#11 15 NA 5 NA
#12 15 NA 7 NA
数据
df1 <- structure(list(cnpj = c(12L,12L,13L,14L,15L,15L),time2 = c(-1L,0L,1L,-1L,2L,3L,NA,NA),n_act_contracts = c(10L,8L,6L,5L,7L,7L)),class = "data.frame",row.names = c(NA,-12L))
,
data.table
选项
setDT(df)[,zero_n_act_contracts := n_act_contracts[!time2],cnpj]
给予
> df
cnpj time2 n_act_contracts zero_n_act_contracts
1: 12 -1 10 8
2: 12 0 8 8
3: 12 1 6 8
4: 13 -1 3 5
5: 13 0 5 5
6: 13 1 7 5
7: 14 1 3 NA
8: 14 2 5 NA
9: 14 3 7 NA
10: 15 NA 3 NA
11: 15 NA 5 NA
12: 15 NA 7 NA