问题描述
我的代码是这样的:
fcase(V2009 == 9L & V3006 == 2L,V1032,V2009 == 10L & V3006 == 3L,V2009 == 11L & V3006 == 4L,V2009 == 12L & V3006 == 5L,V2009 == 13L & V3006 == 6L,V2009 == 14L & V3006 == 7L,V2009 == 15L & V3006 == 8L,V2009 == 16L & V3006 == 9L,V2009 == 17L & V3006 == 10L,default = NA_integer_)
我认为在循环中看起来会更好,例如:
fcase(for(i in 9L:17L){
for(j in 2L:10L){
V2009 == i & V3006 == j,V1032}},default = NA_integer_ )
当然这样代码不会运行,但是有吗?
解决方法
由于条件遵循一个模式,而不是编写多个表达式,paste
列/对象连同值一起匹配并使用 %in%
library(data.table)
fcase(paste(V3006,V2009) %in% paste(2:10,2:10 + 7),V1032,default = NA_integer_)
将 fifelse
与 for
循环一起使用
v1 <- 2L:10L
v2 <- 9L:17L
out <- rep(NA_integer_,length(V1032))
for(i in seq_along(v1)) out <- fifelse(V2009 == v2[i] &
V3006 == v1[i],out)
,
您可以制作一堆列表,然后使用 do.call
将所有输入拼凑到 fcase
中:
示例数据:
dat <- data.table(V2009 = 6:10,V3006 = 5:1,V1032=rep(1L,5))
普通话:
dat[,fcase(
V2009 == 9L & V3006 == 2L,V2009 == 10L & V3006 == 3L,default = NA_integer_
)
]
#[1] NA NA NA 1 NA
do.call
简写:
dat[,do.call(fcase,rbind(Map(
function(i,j) V2009 == i & V3006 == j,9:17,2:10),.(V1032))) ]
#[1] NA NA NA 1 NA