在给定许多条件的情况下,创建虚拟变量的最简单方法是什么。
例如,假设我有以下数据帧(数据):
birth ID
1958 176
1958 178
1959 300
1959 301
1960 500
1960 600
1961 216
1961 201
1962 100
我想创建一个符合条件的新变量,如果满足以下任一条件,则为1:
出生年份是1958年,身份证号码大于175;出生年份是1959年,ID大于320,出生年份是1960年,ID大于341 ......依此类推。
我知道我可以用许多ifelse命令做到这一点,但我希望有一种更简约的方法来做到这一点。
数据
data <- structure(list(birth = c(1958L, 1958L, 1959L, 1959L, 1960L, 1960L, 1961L, 1961L, 1962L),
ID = c(176L, 178L, 300L, 301L, 500L, 600L, 216L, 201L, 100L)),
.Names = c("birth", "ID"), class = "data.frame", row.names = c(NA, -9L))
答案 0 :(得分:6)
又一种方式
data <- structure(list(birth = c(1958L, 1958L, 1959L, 1959L, 1960L, 1960L, 1961L, 1961L, 1962L),
ID = c(176L, 178L, 300L, 301L, 500L, 600L, 216L, 201L, 100L)),
.Names = c("birth", "ID"), class = "data.frame", row.names = c(NA, -9L))
假设您有一个年份的向量匹配1-1与ID切割点,例如
year <- data$birth
id <- c(175, 320, 341, seq(360, 1000, length.out = 6))
cbind(year, id)
# year id
# [1,] 1958 175
# [2,] 1958 320
# [3,] 1959 341
# [4,] 1959 360
# [5,] 1960 488
# [6,] 1960 616
# [7,] 1961 744
# [8,] 1961 872
# [9,] 1962 1000
使用match
within(data, idx <- +(ID[match(birth, year)] >= id))
# birth ID idx
# 1 1958 176 1
# 2 1958 178 0
# 3 1959 300 0
# 4 1959 301 0
# 5 1960 500 1
# 6 1960 600 0
# 7 1961 216 0
# 8 1961 201 0
# 9 1962 100 0
答案 1 :(得分:4)
您可以使用Reduce类型操作。例如
years <- 1958:1960
ids <- c(175, 320, 341)
Reduce(function(a, b) {
a | (data$birth==b[[1]] & data$ID>b[[2]])
}, Map(list, years, ids), init=F)
在这里,我们使用Map
制作年份/ ID对,然后使用Reduce
进行迭代。基本上它将所有条件组合在一起。对于匹配的任何行,这将返回TRUE。
答案 2 :(得分:4)
需要改变名称,但这种方法适合加入:
library(data.table)
lookupDF = data.table(birth=c(1958,1959,1960), ID=c(175,320,341))
lookupDF[setDT(data), on='birth'][,ID:=+(ID>=i.ID)]
# birth ID i.ID
#1: 1958 0 176
#2: 1958 0 178
#3: 1959 1 300
#4: 1959 1 301
#5: 1960 0 500
#6: 1960 0 600
#7: 1961 NA 216
#8: 1961 NA 201
#9: 1962 NA 100
答案 3 :(得分:2)
您可以使用粘贴来创建具有逻辑条件的字符串。然后需要对该字符串进行评估,以便在ifelse
中使用。
cond = paste("(df$birth >", c(1958:1960),"& df$ID >", c(175, 320, 341), ")", collapse=" | ")
ifelse(eval(parse(text=cond)), 1,0)