各州の整数値を取得する簡単な方法の 1 つは、値を整数にキャストし、各列に右底を掛けることです。
私のバージョンは次のとおりですmakecheck2
。使用しているバージョンpaste
はmakecheck2
です。paste
使用するバージョンも変更して、match
複数の値を同時にチェックできるようにしました。どちらのバージョンも、一致を取得するために使用される関数を返すようになりました。
私のバージョンのセットアップはより高速です。0.065 秒対 1.552 秒。
N <- 5
I <- rep(10,N)
S <- as.matrix(expand.grid( lapply(1:N, function(i) { 0:I[i]}) ) )
system.time(f1 <- makecheck1(S))
# user system elapsed
# 1.547 0.000 1.552
system.time(f2 <- makecheck2(S))
# user system elapsed
# 0.063 0.000 0.065
ここでは、1 ~ 10000 の値でテストして確認します。このpaste
バージョンは、値が小さいほど高速です。私のバージョンは、大きな値の方が高速です。
> set.seed(5)
> k <- lapply(0:4, function(idx) sample(1:nrow(S), 10^idx))
> s <- lapply(k, function(idx) S[idx,])
> t1 <- sapply(s, function(x) unname(system.time(for(i in 1:100) f1(x))[1]))
> t2 <- sapply(s, function(x) unname(system.time(for(i in 1:100) f2(x))[1]))
> data.frame(n=10^(0:4), time1=t1, time2=t2)
n time1 time2
1 1 0.761 1.512
2 10 0.772 1.523
3 100 0.857 1.552
4 1000 1.592 1.547
5 10000 9.651 1.848
両方のバージョンのコードは次のとおりです。
makecheck2 <- function(m) {
codes <- vector("list", length=ncol(m))
top <- vector("integer", length=ncol(m)+1)
top[1L] <- 1L
for(idx in 1:ncol(m)) {
codes[[idx]] <- unique(m[,idx])
top[idx+1L] <- top[idx]*length(codes[[idx]])
}
getcode <- function(x) {
out <- 0L
for(idx in 1:length(codes)) {
out <- out + top[idx]*match(x[,idx], codes[[idx]])
}
out
}
key <- getcode(m)
f <- function(x) {
if(!is.matrix(x)) {
x <- matrix(x, ncol=length(codes))
}
match(getcode(x), key)
}
rm(m) # perhaps there's a better way to remove these from the closure???
rm(idx)
f
}
makecheck1 <- function(m) {
n <- ncol(m)
statecodes <- apply(m,1,function(x) paste(x,collapse=" ") )
rm(m)
function(x) {
if(!is.matrix(x)) {
x <- matrix(x, ncol=n)
}
x <- apply(x, 1, paste, collapse=" ")
match(x, statecodes)
}
}