8

私がやりたいのは、単純な恥ずかしいことですが、それでも失敗します。

「文字」と「数値」を含むdata.frameがあります。data.frameの列の1つは、重みを表します。

データフレームのすべてのセルに対応する重みを掛けたい(数値の場合)。

どうすればよいですか(ネストされたループを使用しないのが最適です)。

前もって感謝します!

例:

   c1   c2   w   
l1 abc  2    1
l2 dxf  3    0.5
l3 ghi  4    1.5

になる必要があります

   c1   c2   w   
l1 abc  2    1
l2 dxf  1.5  0.5
l3 ghi  6    1.5
4

4 に答える 4

6

再現可能な例として、は、重みddである変数タイプが混在するデータフレームです。W

dd <- data.frame(G=gl(2,2), X=rnorm(4), Y=1L:4L, Z=letters[1:4], W=0.3:3.3)
num.vars <- names(dd)[sapply(dd, is.numeric)]  #select numeric variables
num.vars <- setdiff(num.vars, "W")  # remove the weight variable
dd[num.vars] <- dd[num.vars] * dd$W  # multiply
于 2011-02-23T14:08:01.227 に答える
5

Vectorise!

> dat <- data.frame(c1 = c("abc","dxf","ghi"), c2 = 2:4, w = c(1,0.5,1.5))

事実上、必要ですc2 * wが、Rにデータフレームの内部を調べるように指示する必要があります。

> with(dat, c2 * w)
[1] 2.0 1.5 6.0

datこれを1行で挿入し直すことができます。

> dat <- within(dat, c3 <- c2 * w)
> dat
   c1 c2   w  c3
1 abc  2 1.0 2.0
2 dxf  3 0.5 1.5
3 ghi  4 1.5 6.0

(既存のものを上書きしたい場合は、に置き換えc3てください。)c2c2

重み以外の数値列が複数ある場合、それを自動化する場合は、わずかに異なる戦略が必要です(つまり、どの列に乗算するかをRに指示しないでくださいw)。

> ## dummy data
> dat2 <- data.frame(c1 = c("abc","dxf","ghi"), c2 = 2:4, w = c(1,0.5,1.5),
                     c3 = 5:7, c4 = 3:5)
> ## select the columns we want, all numerics, but not `w`
> want <- sapply(dat2, is.numeric) & names(dat2) != "w"
> ## then use want to index into dat2
> dat2[, want] <- with(dat2, dat2[, want] * w)
> dat2
   c1  c2   w   c3  c4
1 abc 2.0 1.0  5.0 3.0
2 dxf 1.5 0.5  3.0 2.0
3 ghi 6.0 1.5 10.5 7.5
于 2011-02-23T14:07:37.490 に答える
2

一行でそれを作ろうとする喜びのためだけに(しかし実際には最も読みやすいわけではありません!):

R> dd <- data.frame(G=gl(2,2), X=rnorm(4), Y=1L:4L, Z=letters[1:4], W=0.3:3.3)
R> dd
  G         X Y Z   W
1 1 0.2319565 1 a 0.3
2 1 0.4242205 2 b 1.3
3 2 0.5218064 3 c 2.3
4 2 0.7155944 4 d 3.3

R> data.frame(lapply(subset(dd, select=-W), function(v, w=dd$W) { if (is.numeric(v)) v*w else v }), W=dd$W)
  G          X    Y Z   W
1 1 0.06958695  0.3 a 0.3
2 1 0.55148670  2.6 b 1.3
3 2 1.20015475  6.9 c 2.3
4 2 2.36146163 13.2 d 3.3
于 2011-02-23T14:23:42.073 に答える
1

これまで見てきたように、これを行うにはいくつかの方法がありますが、どういうわけか、本当に簡単な方法が1つ期待され、それが存在するかどうかはわかりません。近くにあるcolwiseと呼ばれるplyrパッケージにライブラリ関数がありますが、私はそれをあなたが望むことを正確に実行させるためのクリーンな方法を思い付くことができません。私がcolwiseでできる最善のことは、これです(データフレームの名前がdfであると仮定します)。

w2<-df$w df<-colwise(function(x,w){if(is.numeric(x)){x*w} else{x}})(df,df$w) df$w<-w2

colwiseに精通している人にとっては、数値以外の列がまったく出力されないため、単にnumcolwiseを使用できるとは思いません。そして、乗算を重みに適用しないためのクリーンな方法を理解することはできません。そのため、ここで乗算を保存して復元するだけです。これを行うためのよりクリーンな方法がうまくいくことができれば、colwiseはこれを行うための素晴らしいシンプルで理解しやすい方法だと思います。

于 2011-02-23T20:25:21.823 に答える