3

コードを書きました。私がやろうとしていることを行うためのより良い方法を提案していただければ幸いです。dt は次のように与えられます。

   SIC FYEAR AU       AT
1    1  2003  6  212.748
2    1  2003  5 3987.884
3    1  2003  4  100.835
4    1  2003  4 1706.719
5    1  2003  5    9.159
6    1  2003  7   60.069
7    1  2003  5  100.696
8    1  2003  4  113.865
9    1  2003  6  431.552
10   1  2003  7  309.109 ...

私の仕事は、特定の SIC の新しい列を作成することです。FYEAR、AT の割合が最も高い AU と、AT の最高値と 2 番目に高い AT の差が値 1 を取得し、それ以外の場合は 0 を取得します。言及されたもの。

a <- ddply(dt,.(SIC,FYEAR),function(x){ddply(x,.(AU),function(x) sum(x$AT))});

   SIC FYEAR AU        V1
1    1  2003  4  3412.619
2    1  2003  5 13626.241
3    1  2003  6   644.300
4    1  2003  7  1478.633
5    1  2003  9     0.003
6    1  2004  4  3976.242
7    1  2004  5  9383.516
8    1  2004  6   457.023
9    1  2004  7   456.167
10   1  2004  9   238.282

ここで、V1 は、特定の SIC および FYEAR の特定の AU のすべての行の合計 AT を表します。次に私は:

a$V1 <- ave(a$V1, a$SIC, a$FYEAR, FUN = function(x) x/sum(x));

   SIC FYEAR AU           V1
1    1  2003  4 1.780949e-01
2    1  2003  5 7.111150e-01
3    1  2003  6 3.362420e-02
4    1  2003  7 7.716568e-02
5    1  2003  9 1.565615e-07
6    1  2004  4 2.740114e-01
7    1  2004  5 6.466382e-01
8    1  2004  6 3.149444e-02
9    1  2004  7 3.143545e-02
10   1  2004  9 1.642052e-02

列 V1 は、指定された SIC および FYEAR の AT 貢献に対する各 AU のパーセンテージ値を表します。次、

a$V2 <- ave(a$V1, a$SIC, a$FYEAR, FUN = function(x) {t<-((sort(x, TRUE))[2]); 
                                                    ifelse((x-t)> 0.1,1,0)});

   SIC FYEAR AU           V1 V2
1    1  2003  4 1.780949e-01  0
2    1  2003  5 7.111150e-01  1
3    1  2003  6 3.362420e-02  0
4    1  2003  7 7.716568e-02  0
5    1  2003  9 1.565615e-07  0
6    1  2004  4 2.740114e-01  0
7    1  2004  5 6.466382e-01  1
8    1  2004  6 3.149444e-02  0
9    1  2004  7 3.143545e-02  0
10   1  2004  9 1.642052e-02  0

特定の SIC の AU と、AT への寄与率が最も高い FYEAR で、差が 10% を超える場合、その AU は 1 になり、そうでない場合は 0 になります。

次に、結果を元のデータ dt とマージします。

dt <- merge(dt,a,key=c("SIC","FYEAR","AU"));

   SIC FYEAR AU       AT           V1 V2
1    1  2003  4 1706.719 1.780949e-01  0
2    1  2003  4  100.835 1.780949e-01  0
3    1  2003  4  113.865 1.780949e-01  0
4    1  2003  4 1491.200 1.780949e-01  0
5    1  2003  5 3987.884 7.111150e-01  1
6    1  2003  5  100.696 7.111150e-01  1
7    1  2003  5   67.502 7.111150e-01  1
8    1  2003  5 9461.000 7.111150e-01  1
9    1  2003  5    9.159 7.111150e-01  1
10   1  2003  6  212.748 3.362420e-02  0

私がしたことは非常に面倒です。同じことを行うためのより良い方法はありますか?ありがとう。

4

2 に答える 2

3

を使用したバージョンは次のdata.tableとおりです。

require(data.table)
DT <- data.table(your_data_frame)
setkey(DT, SIC, FYEAR, AU)
DT[setkey(DT[, sum(AT), by=key(DT)][, V1 := V1/sum(V1), 
          by=list(SIC, FYEAR)])[, V2 := (V1 - V1[.N-1] > 0.1) * 1, 
          by=list(SIC, FYEAR)]]

この部分は、DT[, sum(AT), by=key(DT)][, V1 := V1/sum(V1), by=list(SIC, FYEAR)]最初にAT3 つの列すべてを合計してから、V1 を V1/sum(V1) by columns SIC, FYEARby reference に置き換えます。このsetkeyコードをラップすると、4 つの列すべてが順序付けられます。したがって、最後から 2 番目の値は常に 2 番目に高い値になります (重複する値がないという条件の下で)。V2これを使用して、 as: [, V2 := (V1 - V1[.N-1] > 0.1) * 1, by=list(SIC, FYEAR)]]by referenceを作成できます。これができたら、 をjoin使用して実行できますDT[.]

お役に立てれば。

于 2013-11-13T16:50:06.977 に答える