2016-08-25 15 views
0

のために私は本当に私は「これを下回るdata.tableに示すように、すべての変数abdg & Nは複数のバージョンを持っているモデルを実行する関数を作成するために苦労していますcrm名付けまし:Rループは一致data.table列

変数がモデルに入力されたとして lnNの値を計算し、見出しの同じ番号を持つ列にそれを置くために、以下の機能を実行している私は何をしようとしている
crm = data.table(
    East = 26500, 
    North = c(115000, 120000, 125000, 130000, 135000, 140000), 
    rain = c(1049.61, 1114.31, 1361.61, 1407.2, 1499.56, 1654.13), 
    crop = 'Wheat', area = c(0.1718, 0.1629, 0.1082, 0.0494, 0.02, 0.004), 
    rn = c("10007", "10018", "10023", "10024", "10025", "10026"), 
    N1 = 184.262648839489, N2 = 180.312874871521, N3 = 178.615847839997, 
    N4 = 182.531626054579, a1 = 0.186117715072018, a2 = -0.0232731908915799, 
    a3 = 0.227017532149122, a4 = 0.162943230565506, b1 = 0.000478900233700419, 
    b2 = 0.000787931973696371, b3 = 0.000458478256537521, b4 = 0.000517304324750896, 
    d1 = -0.000328164576390286, d2 = -0.000112122093240884, d3 = 0.000112702113716146, 
    d4 = 7.40875908059628e-05, g1 = 4.04709473710477e-06, g2 = 3.68724096485995e-06, 
    g3 = 3.47214450131546e-06, g4 = 3.55825543257538e-06, key = 'rn' 
) 

。私。 a1b1d1g1 & N1を使用すると、すべての2s、3s、4sの列lnN1などが生成されます。

n <- 1:4 
cols <- paste0("lnN",n) 
for(i in 1:length(n)){ 
crm[,(cols) := lapply(.SD ,function (x) { 
    N = crm[,7+i] 
    a = crm[,11+i] 
    b = crm[,15+i] 
    d = crm[,19+i] 
    g = crm[,23+i] 
a + (b*crm[,rain]) + (g*N) + (d*crm[,rain]*N)}), .SDcols = paste0("N",n)] 

}

私はどこでもこれを実現する方法についての例を見つけるしたことはありません。私はmapplyを使ってみましたが、各変数のすべての反復をどのように反復処理するかはわかりません。ご協力ありがとうございました!どのように

+1

"これを達成する方法については、どこにも例がありません。"この場合、あなたのデータ構造に欠陥があることを示唆していると思います。私は '(cols):='を4回上書きしているので、あなたがしようとしていることを理解することは非常に難しいと思います。とにかく、私は 'melt(crm、meas = patterns("^N "、"^a "、"^b "、"^d "、"^g ")、value.name = c "、" a "、" b "、" d "、" g "))と列番号で手を出すのではなく、そこから作業する方法を見つけることができます。 – Frank

+0

@Frank提案していただきありがとうございます。私は不確実性の値を得るためにモンテカルロ法の一環として各変数の多変量データを生成する必要があるので、データをどのように構造化するかを考えることはできません。私はあなたの提案を見て、私ができることを見ます。 –

+1

あなたが分析を繰り返すにつれて、@Frankが言ったことを考えると、2番目のほうがいいでしょう(しかし、 "^ N"は '' N '[0-9] ''のようなものかもしれません。 。これを行うと、あなたの数式を 'dd [、lnN:=。(a +(b * rain)+(g * N)+(d * rain * N))]'で適用することができ、必要に応じて 'group_by'を実行します。 –

答えて

2

library(dplyr) 
cbind(crm, do.call(cbind, 
    lapply(1:4, function(x) { 
    select(crm, c(contains(as.character(x)), rain)) %>% 
     setnames(gsub("[0-9]", "", names(.))) %>% 
     transmute(lnN = a + (b*rain) + (g*N) + (d*rain*N)) %>% 
     setnames(paste0("lnN", x)) 
    }) 
)) 

主な考え方は、数(ともrain)を含有するカラムだけを選択し、それぞれの番号のため、である、数字を削除する式を適用し、名前を変更する列の名前を変更結果の列に数値を追加し、次にcbindの結果を元のテーブルに追加します。

+0

興味深い。 data.tableの最後に 'lnN'カラムは作成されていないようですが、コード内のロジックを見ることができます。私はそれと遊びをし、私が間違って何をしたのか見てみましょう! –

+1

私のマシンで正常に動作します...出力に名前を割り当てましたか?私。 '出力< - cbind(crm、do.call(cbind、...'または元のオブジェクト 'crm < - cbind(crm ...')。 –

+0

ああああ...長い一日です!助けてくれてありがとう! –

0

フランクとウィーワンの両方の反復回数を変更しようとすると、上記のコメントを見て、問題が発生する可能性があることがわかったので、データの構造を再考しました。

代わりに、ランダムに生成された行列を別々のデータフレームとして残していました。 ernmで(今Nitと呼ばれる)Nabg & dのための多変量ランダムな値が含まれています。従ってcrmは最初の6つの列しか持たないようになりました。 1の各反復について

for(i in 1:n){ 
    a = e[1,i] 
    b = e[2,i] 
    g = e[3,i] 
    d = e[4,i] 
Nit = rnm[i] 
bob = a + (b*crm$rain) + (g*Nit) + (d*crm$rain*Nit) 
data.y <- cbind(data.y, bob) 
} 
crm <- cbind(crm, data.y) 
names(crm)[c(7:n)] = names(bobs) 

:コードは次のようになり、Nは、各パラメータ(すべて1、すべて2S、等)のi値を読み込み、モデルにそれを置き、Aが作成しますbobと呼ばれる列。 bobは、関数(data.y)の前に作成した空のデータフレームにマージされます。これは、所望の回数のループが達成されるまでループする。

.csvファイルから読み込まれることbob.nbob.1を番号Iは、私は列見出しのリストを含むデータフレームbobsに格納された名前を使用して、順次全てbob列の名前を変更する前に、2つをマージするcbindを使用Excelで作成。

0

ここで提供する名前を利用するpatternsためmeltnewly implemented機能を活用melt - と - dcastrecast)バージョンがあります。これは現在開発中の機能であるため、手順についてはInstallation wikiを参照してください。

library(data.table) 1.10.5+ 
# create character version of 1:N (Number of output columns) 
N = paste0(seq_len(length(grep('^b', names(crm))))) 
# join crm to a melt & recast version of itself using rain as 
# the join key (note this will fail if the amount of rain may 
# not be unique -- in this case, we should include some ID in 
# id.vars, like rn, and adjust accordingly) 
crm = crm[crm[ , melt(.SD, id.vars = 'rain', 
         measure.vars = patterns(N = '^N[0-9]', a = '^a[0-9]', 
               b = '^b', d = '^d', g = '^g')) 
       # use the formula to generate ln 
       ][ , ln := a + b*rain + g * N + d * rain * N 
        # reshape wide 
        ][ , dcast(.SD, rain ~ variable, value.var = 'ln') 
        # rename the columns here 
        ][ , setnames(.SD, N, paste0('ln', N))], 
      on = 'rain'] 

# by-reference version 
crm[crm[ , melt(.SD, id.vars = 'rain', 
       measure.vars = patterns(N = '^N[0-9]', a = '^a[0-9]', 
             b = '^b', d = '^d', g = '^g')) 
     # use the formula to generate ln 
     ][ , ln := a + b*rain + g * N + d * rain * N 
      # reshape wide 
      ][ , dcast(.SD, rain ~ variable, value.var = 'ln')], 
    # mget tends to be sort of slow, which is why I used the 
    # assign-by-copy approach first above; in larger examples, 
    # this slow-down may be outweighed by the cost of copying 
    paste0('ln', N) := mget(N), on = 'rain']