2017-02-21 5 views
1

「カテゴリ」グループによってdata.frameにスケーリング関数を適用しようとしています。スケーリング関数は、そのカテゴリーに応じて特定のスカラーを必要とします。計算は、 't'の各値を 'cat'の 't'の合計で割った後、 'cat'と一致するスカラー(cat = aの場合は 'fac.a'など)を乗算します。 。適用関数のグループごとにテキストで変数を取得

私は特定のスカラーを呼び出すには「取得」を使用しますが、それだけで1行目の値を使用して、全体data.frameに適用されます。

# my scaling factors: 
fac.a <- 15 
fac.b <- 12 
fac.c <- 20 

# dummy data.frame 
set.seed(10) 
df <- data.frame(t = sample(1:100,15),cat = rep(c("a","b","c"),each=5)) 

# apply function that groups & sums the df$t values by df$cat, divides each df$t by its 
# repsective category total and applies the correct scalar with a get function. 
df$scaled <- apply(df[1], 2, function(x) (df$t/ave(df$t, df$cat, FUN=sum))*get(paste0("fac.",df$cat))) 

は、残念ながら、私は唯一の権利を取得していますget関数は第1スカラーを呼び出しているだけなので、第1カテゴリーの答え。

これは、4〜5行(別の属性の構築など)で比較的簡単に行うことができますが、私は適用機能でそれを実現したいと思います。

N.B.なぜdata.frameでは "t"という新しい属性がありますが、名前(df)を調べると "縮尺"されていますか?

答えて

1

我々はdata.table

library(data.table) 
setDT(df)[, newt := sum(t), cat][, 
    scaled := (t/newt) * get(paste0('fac.', cat)), 1:nrow(df)][, newt := NULL][] 
#  t cat scaled 
# 1: 51 a 3.8059701 
# 2: 31 a 2.3134328 
# 3: 42 a 3.1343284 
# 4: 68 a 5.0746269 
# 5: 9 a 0.6716418 
# 6: 22 b 1.1046025 
# 7: 26 b 1.3054393 
# 8: 94 b 4.7196653 
# 9: 57 b 2.8619247 
#10: 40 b 2.0083682 
#11: 59 c 3.6875000 
#12: 100 c 6.2500000 
#13: 10 c 0.6250000 
#14: 52 c 3.2500000 
#15: 99 c 6.1875000 

使用することができますまたはより高速なオプションは、キー/値のデータセットを作成する「スケール」列を作成するには、元のデータと結合することであろう

df2 <- setnames(setDT(stack(mget(ls(pattern="fac\\.")))[2:1]), 
         1, "cat")[, cat := sub(".*\\.", "", cat)][] 
setDT(df)[df2, scaled := (t/sum(t))*values, on = .(cat), by = .EACHI] 
df 
#  t cat scaled 
# 1: 51 a 3.8059701 
# 2: 31 a 2.3134328 
# 3: 42 a 3.1343284 
# 4: 68 a 5.0746269 
# 5: 9 a 0.6716418 
# 6: 22 b 1.1046025 
# 7: 26 b 1.3054393 
# 8: 94 b 4.7196653 
# 9: 57 b 2.8619247 
#10: 40 b 2.0083682 
#11: 59 c 3.6875000 
#12: 100 c 6.2500000 
#13: 10 c 0.6250000 
#14: 52 c 3.2500000 
#15: 99 c 6.1875000 
+0

うん、私はdata.tableの熱心なユーザーです、それは大好きです。しかし、私は必死にgetを使ってこのことを理解しようとしています。おそらく私はばかげていますが、それは私が解決したい問題です!あなたの答えはありがとう – Sam

+0

@Samここでは 'apply'を使用しないほうが良いでしょう。単一の列があり、' apply'が出力を 'matrix'に変換するからです。 – akrun

+0

大丈夫です。また、縮尺率は少し低くなります。たとえば、最初の縮尺率は3.8程度です。私はスカラーで乗算する代わりに分割したと思う、私はそれが私のやや貧しい質問であることを賭けている:) – Sam

関連する問題