多重比較マッチング関数 -- ifelse 関数の一般化 -- (2004.12.22)
w <- mifelse(x,y,pattern) は
(1) x[a] == y[b] なら w[a] <- z[b] とする。
(2) もしすべての y[b] と一致しない x[a] があれば w[a] <- others(既定値 NA)
とする。
mifelse <- function(x, y, pattern, others=NA) { if(length(pattern)!=length(y)) stop("length(pattern) should be equal to length(y)") w <- rep(others, length(x)) for (i in 1:length(y)) w[which(x==y[i])] <- pattern[i] return(w) }
実は一行で書ける
w <- pattern[match(x,y)] # ただしマッチしない要素は NA とされる
> mifelse(x=c(1,1,2,4,3,2,2,1), y=c(1,2,3,4), letters[1:4]) [1] "a" "a" "b" "d" "c" "b" "b" "a" > mifelse(x=c(1,1,2,4,3,2,2,1), 1:4, 1:4) [1] 1 1 2 4 3 2 2 1 > mifelse(x=c(1,1,2,4,3,2,2,1), 4:1, 1:4) [1] 4 4 3 1 2 3 3 4 # x[9] は y のどれとも一致しないので others の値 10 が返される > mifelse(x=c(1,1,2,4,3,2,2,1,0), y=c(1,2,3,4), letters[4:1], others=10) [1] "d" "d" "c" "a" "b" "c" "c" "d" "10" > mifelse(x=c(1,1,2,4,3,2,2,1,0), y=c(1,2,3,4), letters[4:1]) [1] "d" "d" "c" "a" "b" "c" "c" "d" NA
# ifelse 関数のエミュレーション例 > x=1:10; ifelse(x<5, "x<5", "x>=5") [1] "x<5" "x<5" "x<5" "x<5" "x>=5" "x>=5" "x>=5" "x>=5" "x>=5" "x>=5" > x=1:10; mifelse(x<5, c(TRUE,FALSE), c("x<5","x>=5")) [1] "x<5" "x<5" "x<5" "x<5" "x>=5" "x>=5" "x>=5" "x>=5" "x>=5" "x>=5"