假设我有一个包含以下两个变量的数据集:
start.year <- c(1957, 1973, 1943, 1991, 2001, 1967)
end.year <- c(1980, 1998, 1965, 2011, 2006, 1984)
db <- data.frame(start.year, end.year)
start.year和end.year分别表示观察期的开始和结束。 我希望创建一组等于1的二分十年变量,当观察期在该特定十年中至少有一年 - 数十年等于1940-1949,1950-195,...... - 否则,0这样:
start.year end.year 40s 50s 60s 70s 80s 90s 00s 10s
1 1957 1980 0 1 1 1 0 0 0 0
2 1973 1998 0 0 0 1 1 1 0 0
3 1943 1965 1 1 1 0 0 0 0 0
4 1991 2011 0 0 0 0 0 1 1 1
5 2001 2006 0 0 0 0 0 0 1 0
6 1967 1984 0 0 1 1 1 0 0 0
我看到cut
函数,但它看起来 - 我可能错了 - 当要切割的变量实际上是由两个变量而不是一个连续变量构成的范围时,这不适合这个特定任务
您会建议采用什么方法?有一种灵活的方式,以便我可以在将来适应这一点,让我们说,当观察期至少有2/3/4(...)/ 9年时,二分十年变量等于1那个特定的十年?
谢谢!
答案 0 :(得分:3)
我们可以floor
到几十年,然后在Map
获得来自&#39; start.year&#39;的序列。到&#39; end.year&#39;,并将其转换为table
res <- cbind(db, as.data.frame.matrix(table(stack(setNames(Map(function(x, y)
seq(x, y, by = 10),
(db$start.year %/% 10) * 10, (db$end.year %/% 10)*10), seq_len(nrow(db))))[2:1])))
names(res)[-(1:2)] <- substr(names(res)[-(1:2)], 3, 4)
res
# start.year end.year 40 50 60 70 80 90 00 10
#1 1957 1980 0 1 1 1 1 0 0 0
#2 1973 1998 0 0 0 1 1 1 0 0
#3 1943 1965 1 1 1 0 0 0 0 0
#4 1991 2011 0 0 0 0 0 1 1 1
#5 2001 2006 0 0 0 0 0 0 1 0
#6 1967 1984 0 0 1 1 1 0 0 0
如果我们使用tidyverse
library(purrr)
library(dplyr)
db %>%
mutate_all(funs((.%/%10)*10)) %>%
transmute(ind = row_number(), i1 = 1,
year = map2(start.year, end.year, ~seq(.x, .y, by = 10))) %>%
unnest %>%
spread(year, i1, fill = 0) %>%
select(-ind) %>%
rename_all(substr, 3, 4) %>%
bind_cols(db, .)
# start.year end.year 40 50 60 70 80 90 00 10
#1 1957 1980 0 1 1 1 1 0 0 0
#2 1973 1998 0 0 0 1 1 1 0 0
#3 1943 1965 1 1 1 0 0 0 0 0
#4 1991 2011 0 0 0 0 0 1 1 1
#5 2001 2006 0 0 0 0 0 0 1 0
#6 1967 1984 0 0 1 1 1 0 0 0