2

私はオンラインで広範囲に調べましたが、この特定の質問に対する答えは見つかりませんでした (私は思います)。

私が自分自身を説明する最良の方法は、私の問題を再現するコードを使用することです。私はいくつかの一時データを作成しました:

x <- runif(100,1,2)
y <- runif(100,2,3)

z <- c(rep(1,100))
temp <- cbind(x,y,z)

temp[1:25,3] = temp[1:25,3] +2

temp <- as.data.frame(temp)

そして、これはtempがどのように見えるかです

         x        y   z
1   1.512620 2.552271 3
2   1.133614 2.455296 3
3   1.543242 2.490120 3
4   1.047618 2.069474 3
.      .        .     .
.      .        .     .
27  1.859012 2.687665 1
28  1.231450 2.196395 1

データ フレームの最後 (100 行) まで続きます。

私がやりたいことは、関数をデータ フレームに適用することですが、データのサブセットに適用することです。たとえば、z=3 の場合は x 列と y 列に関数 mean を適用し、z=1 の場合は列 x と y に関数 mean を適用します。つまり、z=1 と z=3 のときの x の平均と、z=1 と z=3 のときの y の平均です。私の実際のデータセットでは、z= ある値の場合の行数は大きく異なります。

私は動作する次のコードを使用しています。ただし、コードがより効率的になり、理想的には for ループを回避できるように感じるので、非常に不安になります。

x <- c(unique(temp$z))

^^ を使用して一意の z 値を取得します (この場合は z=3 および z=1)。

for(i in x){
  assign(paste("newdata",i,sep=""),subset(temp[which(temp$z==i),],select=c("x","y")))
} 

そのため、行数が同じではない 2 つの新しいデータ フレーム newdata1 と newdata3 ができました。z=1 の場合、newdata1 はすべての値を持ち、z=3 の場合、newdata3 はすべての値を持ちます。

library(gdata)

blah <-cbindX(newdata1,newdata3)

cbindX を使用して、サブセット化されたデータを再び 1 つの大きなデータ フレームに結合します。なぜこれを正確に行うのかわかりません(このコードはずっと前に作成しました)。私が覚えているのは、上記の for ループを使用するときにこれを機能させる唯一の方法だということだけです。コードの主な問題は、複数の z 値があり、そのリストに手動で入力するのが非常に面倒になることです。z の範囲が 1 から 50 の場合、ユーザーは newdata1、newdata2、newdata3 .... などと入力します。

しかし...それはうまくいきます:

summ.test <- apply(blah,2,function(x) { 
c(min(x,na.rm=TRUE),median(x,na.rm=TRUE),max(x,na.rm=TRUE),sum(!is.na(x)))})

         x         y         x         y
[1,]  1.028332  2.018162  1.012379  2.009595
[2,]  1.509049  2.504000  1.427981  2.455296
[3,]  1.992704  2.998483  1.978359  2.970695
[4,] 75.000000 75.000000 25.000000 25.000000

したがって、私が効果的に行ったのは、以前からサブセット化した値を使用して新しいデータ フレームを作成し、対象の関数をそれらに適用することでした。したがって、最初の行は、z=1 の場合の x の平均、z=1 の場合の y の平均、z=3 の場合の x の平均、z=3 の場合の y の平均です。

かなり明白な主な問題: データ フレームをサブセット化する for ループ メソッドは、私が望むよりも多くの問題を引き起こします。それを完全に回避し、それでも同じ結果になるための推奨事項はありますか?

これが紛らわしい場合、または私のコードが単にずさんな場合はお知らせください。このサイトでも質問の書式設定に取り組んでいます..

4

3 に答える 3

3
library(data.table)
DT <- as.data.table(temp)
DT[, lapply(.SD, mean), by=z]
   z        x        y
1: 3 1.515801 2.309161
2: 1 1.509637 2.532575

またはベースを使用R

with(temp, cbind(x=tapply(x, z, mean), y=tapply(y, z, mean)))
         x        y
1 1.509637 2.532575
3 1.515801 2.309161

set.seed(1)PS、たとえば、シードを設定することを忘れないでください;)

于 2013-10-09T01:05:17.390 に答える
2
> aggregate( . ~ z, data=temp, FUN=mean)
  z        x        y
1 1 1.505304 2.474642
2 3 1.533418 2.477191

別の列のカテゴリ内の複数の列に同じ関数を適用する場合は、「集計」について考えてください。これは、チルダの前の「ドット」が「z」以外のすべての列の平均を取得することを示す数式引数を取るバージョンです。

于 2013-10-09T01:18:25.027 に答える
1

私がやりたいことは、関数をデータ フレームに適用することですが、データのサブセットに適用することです。

したがって、subsetoraggregate関数を使用できます。

data = data.frame(x = runif(100), y = runif(100), z = sample(1:10, 100, replace = TRUE))

# get z > 3 AND z < 6 subset, for example
new.data = subset(data, z > 3 & z < 6) ## CAUTION: use &, not &&

# use newdata
cm = colMeans(new.data)
print(cm)

#        x         y         z 
#   0.4674450 0.5293915 4.5769231 

それが役に立てば幸い!

于 2013-10-09T01:29:54.053 に答える