我正在尝试创建一堆具有两个条件的虚拟变量,每个条件都基于变量的名称 但是我不确定如何进行
I have the following dataset "dat"
ID Entry Exit y2000 y2001 y2002 y2003 ....
1 1999 2010 0 0 0 0
2 2000 2001 0 ......
3 2002 2003 0 ........
4 1999 2002
5 .....
此刻所有y“ i”变量都等于0 基本上,我想要的是如果入口小于或等于2000而出口大于或等于2000,则将值1分配给变量y2000 类似地,对于变量y2001,如果入口小于或等于2001,出口大于或等于2001,我想分配值1 等等。
我可以对一个signle变量执行以下操作:
dat$y2000[dat$exit >= 2000 & dat$enter <= 2000] <- 1
但是我想为y“ i”类型的每个变量循环执行此操作,该怎么办?
在此先感谢您的帮助
答案 0 :(得分:1)
我们可以使用Map
来做到这一点。使用grep
('nm1')获取'y'列名称的向量,从名称中提取数字部分,使用Map
根据以下内容“替换”对应的“ y”列中的值使用“输入/退出”列创建逻辑条件并更新原始数据集中的“ y”列
nm1 <- grep("^y\\d{4}$", names(dat), value = TRUE)
nm2 <- as.integer(sub("y", "", nm1))
dat[nm1] <- Map(function(x, y) replace(dat[[x]],
dat$Exit >= y & dat$Entry <= y, 1), nm1, nm2)
或使用tidyverse
library(tidyverse)
dat %>%
gather(key, val, matches("^y")) %>%
mutate(colNum = readr::parse_number(key), %>%
val = +(Exit >= colNum & Entry <= colNum)) %>%
select(-colNum) %>%
spread(key, val)
dat <- structure(list(ID = c(1L, 2L, 3L, 5L), Entry = c(1999L, 2000L,
2002L, 1999L), Exit = c(2010L, 2001L, 2003L, 2002L), y2000 = c(0L,
0L, 0L, 0L), y2001 = c(0L, 0L, 0L, 0L), y2002 = c(0L, 0L, 0L,
0L), y2003 = c(0L, 0L, 0L, 0L)), class = "data.frame", row.names = c(NA,
-4L))