我想在 r 中创建持续时间变量,但我还没有弄清楚。我的数据如下所示:
company <- rep(c("A", "B"), each=8)
year <- rep(1980:1987, 2)
value <- c(NA,0,0,0,1,0,-1,1,NA,-3,NA,0,0,1,0,0)
data <- data.frame(company, year, value)
我想要这样
company <- rep(c("A", "B"), each=8)
year <- rep(1980:1987, 2)
value <- c(NA,0,0,0,1,0,-1,1,NA,-3,NA,0,0,1,0,0)
timeduration <- c(NA,1,2,3,1,2,1,1,NA,1,NA,1,2,1,2,3)
data1 <- data.frame(company, year, value, timeduration)
零在值变量中有两个含义。如果我在 NA 之后使用它,我必须从 1 开始计数,但如果 0 来自任何值之后,则意味着值的变化是恒定的。因此,即使值更改为 0,我也必须继续计数。我在第二个数据(data1)中显示了这种情况。(此外,数据应按考虑公司进行分组)。感谢您的努力!
编写一个函数来控制要对变量值执行的操作,例如:
company <- rep(c("A", "B"), each=8)
year <- rep(1980:1987, 2)
value <- c(NA,0,0,0,1,0,-1,1,NA,-3,NA,0,0,1,0,0)
timeduration <- c(NA,1,2,3,1,2,1,1,NA,1,NA,1,2,1,2,3)
data1 <- data.frame(company, year, value, timeduration)
library(tidyverse)
calc_td <- function(x) {
res <- rep(0, length(x))
tmp <- x
tmp[is.na(x)] <- max(x, na.rm = TRUE) + 1
for (i in seq_along(tmp)) {
if (i == 1L) {
res[i] <- 0
} else {
if ((tmp[i] != tmp[i - 1]) & (tmp[i] != 0)) {res[i] <- 1} else {res[i] <- res[i - 1] + 1}
}
}
res[is.na(x)] <- NA
res
}
data1 %>%
group_by(company) %>%
mutate(timeduration2 = calc_td(value)) %>%
ungroup()
我们定义一个对应于 OP 在value
中对零的解释的reset
变量,然后相应地构建group
s(每当时间计数reset
TRUE
时,我们用cumsum()
开始一个新的group
)。
然后我们可以推导出timeduration
作为group
内year
和year
的第一个值之间的差值。
library(dplyr)
data %>%
group_by(company) %>%
mutate(reset = (value != 0) | (value == 0 & is.na(lag(value)))) %>%
group_by(company, group = cumsum(ifelse(is.na(reset), 0, reset))) %>%
mutate(timeduration = ifelse(is.na(value), NA, year - first(year) + 1)) %>%
ungroup() %>%
select(- reset, - group)
#> # A tibble: 16 × 4
#> company year value timeduration
#> <chr> <int> <dbl> <dbl>
#> 1 A 1980 NA NA
#> 2 A 1981 0 1
#> 3 A 1982 0 2
#> 4 A 1983 0 3
#> 5 A 1984 1 1
#> 6 A 1985 0 2
#> 7 A 1986 -1 1
#> 8 A 1987 1 1
#> 9 B 1980 NA NA
#> 10 B 1981 -3 1
#> 11 B 1982 NA NA
#> 12 B 1983 0 1
#> 13 B 1984 0 2
#> 14 B 1985 1 1
#> 15 B 1986 0 2
#> 16 B 1987 0 3