0

この質問のフォローアップがあります。

既存の data.frame の列名と特定の行エントリを条件として data.frame を作成しています。以下は、forループを使用して解決した方法です(@Rolandの提案のおかげで...実際のデータは@eddiの回答の要件に違反していました)が、実際のデータセット(200x500,000 + rows.cols)で実行されていますもう2時間以上…

(次の生成された data.frames は、実際のデータに非常に似ています。)

set.seed(1)
a <- data.frame(year=c(1986:1990),
                events=round(runif(5,0,5),digits=2))
b <- data.frame(year=c(rep(1986:1990,each=2,length.out=40),1986:1990), 
                region=c(rep(c("x","y"),10),rep(c("y","z"),10),rep("y",5)),
                state=c(rep(c("NY","PA","NC","FL"),each=10),rep("AL",5)),
                events=round(runif(45,0,5),digits=2))
d <- matrix(rbinom(200,1,0.5),10,20, dimnames=list(c(1:10), rep(1986:1990,each=4)))
e <- data.frame(id=sprintf("%02d",1:10), as.data.frame(d), 
                region=c("x","y","x","z","z","y","y","z","y","y"), 
                state=c("PA","AL","NY","NC","NC","NC","FL","FL","AL","AL"))


 for (i in seq_len(nrow(d))) {
   for (j in seq_len(ncol(d))) {
     d[i,j] <- ifelse(d[i,j]==0,
                      a$events[a$year==colnames(d)[j]],
                      b$events[b$year==colnames(d)[j] &
                               b$state==e$state[i] &
                               b$region==e$region[i]])
   }
 }

これを行うためのより良い/より速い方法はありますか?

4

2 に答える 2

0

それを行うためのより簡単な方法は次のとおりです(私が思うに、溶解、キャスト、マージは必要ありません)。

まず、a および b 配列は、年 (a の場合) および年/州/地域 (b の場合) でインデックス付けする必要があります。

at = a$events; names(at) = a$year

bt = tapply(b$events,list(b$year,b$state,b$region),function(x) min(x))
# note, I used min(x) in tapply just to be on the safe side, that the functions always returns a scalar

# we now create the result of the more complex case (lookup in b)
ids = cbind(colnames(d)[col(d)],
            as.character(e$state[row(d)]),
            as.character(e$region[row(d)])
           )
vals=bt[ids]; dim(vals)=dim(d)
# and compute your desired result with the ifelse
result = ifelse(d==0,at[colnames(d)[col(d)]],vals)
# and that's it!

これは(ネストされたループを回避して)高速になるはずですが、私はそれをプロファイルしていません。それが完全なデータでどのように機能するか教えてください

于 2013-07-23T22:37:21.157 に答える