4

R の強力なベクトル処理機能を使用すると、このコードをより短く、より効率的にできることを私は知っています。現時点では方法がわかりません...

基本的なタスクは、各行内のセルを調整して、行の合計が、別のデータ フレームによって決定される定義済みの数と一致するようにすることです。このようにして、各領域の総人口は特定の値に強制されます (各行は領域を表します) が、ある列から次の列に移動するセル間の比率は同じままです。

それを行う醜い方法(最初のループは、サンプルデータフレームを作成するだけです。それはもっとうまくできるはずです。ループの使用をやめることはできません!):

con1 <- array(dim=c(5,3))

set.seed(1066)
for(i in 1:ncol(con1)){
con1[,i] <- round(rnorm(n=5,mean=10,sd=3))}
con1 <- data.frame(con1)
con2 <- data.frame(array(c(8:13, 9:14, 10:15), dim=c(5,3)))

apply(con1,1, sum)
apply(con2,1, sum) # different row totals

con1.adj <- con1
for ( i in 1:nrow(con1)){
  con1.adj[i,1] <- con1[i,1] * ( sum(con2[i,]) / sum(con1[i,]) )
  con1.adj[i,2] <- con1[i,2] * ( sum(con2[i,]) / sum(con1[i,]) )
  con1.adj[i,3] <- con1[i,3] * ( sum(con2[i,]) / sum(con1[i,]) )
}
con1.adj <- data.frame(con1.adj)
apply(con1.adj,1, sum) # same row totals

(コンテキスト: このコードを他の誰かの作品から掘り出し、しばらくの間楽しく使用しました。急な R 学習曲線を少し上に上げた今、私にはひどいように見えます。また、コードを再利用してもらいたい言語を本当に楽しんでおり、これを行うためのより美しい方法を見つけることができれば、さらに楽しむことができます)

4

2 に答える 2

15

私はこのワンライナーが仕事をするべきだと思います:

con1.adj <- con1 * rowSums(con2) / rowSums(con1)
于 2013-02-24T21:52:13.163 に答える
2

con1もう少し良い方法で生成するための別の提案があります

rgen <- function(X,mean=10,sd=3){
  round(rnorm(n=length(X),mean=mean,sd=sd))
}

con1 <- data.frame(apply(con1,2,rgen))

ランダムベクトルのサイズは次元と一致し、異なるものを動的に渡すarrayことができることに注意してください。meansdapply(con1,2,rgen,5,2)rnormmean=5sd=2

于 2013-02-24T22:11:49.840 に答える