8

いくつかの列を使用してデータフレームを分割し、fivenum各グループでたとえば呼び出します。

aggregate(Petal.Width ~ Species, iris, function(x) summary(fivenum(x)))

戻り値は、2列のみのdata.frameで、2番目は行列です。どうすればdata.frameの通常の列に変換できますか?

アップデート

使用するコードが少ない次のようなものが欲しいfivenum

ddply(iris, .(Species), summarise,
      Min = min(Petal.Width),
      Q1 = quantile(Petal.Width, .25),
      Med = median(Petal.Width),
      Q3 = quantile(Petal.Width, .75),
      Max = max(Petal.Width)
      )
4

4 に答える 4

11

これは、を使用したソリューションですdata.table(特に要求されていませんが、またはの代わりに使用することは明らかaggregateですddply。コーディングに少し時間がかかるだけでなく、繰り返し呼び出すquantileと非効率になります。呼び出しごとにデータを並べ替えます。

library(data.table)
Tukeys_five <- c("Min","Q1","Med","Q3","Max") 

IRIS <- data.table(iris)
# this will create the wide data.table
lengthBySpecies <- IRIS[,as.list(fivenum(Sepal.Length)), by = Species]

# and you can rename the columns from V1, ..., V5 to something nicer

setnames(lengthBySpecies, paste0('V',1:5), Tukeys_five)


lengthBySpecies



      Species Min  Q1 Med  Q3 Max
1:     setosa 4.3 4.8 5.0 5.2 5.8
2: versicolor 4.9 5.6 5.9 6.3 7.0
3:  virginica 4.9 6.2 6.5 6.9 7.9

quantileまたは、適切なprob引数を使用するための単一の呼び出しを使用します。

IRIS[,as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25))), by = Species]


       Species  0%   25% 50% 75% 100%
1:     setosa 4.3 4.800 5.0 5.2  5.8
2: versicolor 4.9 5.600 5.9 6.3  7.0
3:  virginica 4.9 6.225 6.5 6.9  7.9  

作成された列の名前は構文的に有効ではないことに注意してください。ただし、を使用して同様の名前変更を行うことができます。setnames


編集

興味深いことに、quantileを設定すると、結果のベクトルの名前が設定されnames = TRUE、これがコピーされます(数値の計算が遅くなり、メモリが消費されます。ヘルプで警告することもできます。空想です!)

したがって、おそらく使用する必要があります

 IRIS[,as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25), names = FALSE)), by = Species]

Rまたは、内部でコピーせずに名前付きリストを返したい場合

IRIS[,{quant <- as.list(quantile(Sepal.Length, prob = seq(0,1, by = 0.25), names = FALSE))
       setattr(quant, 'names', Tukeys_five)
       quant}, by = Species]
于 2013-02-11T01:46:35.280 に答える
5

を使用do.callしてdata.frame、各行列要素を再帰的に呼び出し、ベクトル要素を含むdata.frameを取得できます。

dim(do.call("data.frame",dfr))
[1] 3 7

str(do.call("data.frame",dfr))
'data.frame':   3 obs. of  7 variables:
 $ Species            : Factor w/ 3 levels "setosa","versicolor",..: 1 2 3
 $ Petal.Width.Min.   : num  0.1 1 1.4
 $ Petal.Width.1st.Qu.: num  0.2 1.2 1.8
 $ Petal.Width.Median : num  0.2 1.3 2
 $ Petal.Width.Mean   : num  0.28 1.36 2
 $ Petal.Width.3rd.Qu.: num  0.3 1.5 2.3
 $ Petal.Width.Max.   : num  0.6 1.8 2.5
于 2013-02-07T19:38:44.273 に答える
4

私の知る限り、使用している関数(fivenum)は、'内から列に簡単にバインドできる方法でデータを返さないため、要求していることを実行する正確な方法はありません。 ddply'関数。ただし、これはプログラム的な方法で簡単にクリーンアップできます。

ステップ1fivenum'ddply'関数を使用して、各'Species'値に対して関数を実行します。

data <- ddply(iris, .(Species), summarize, value=fivenum(Petal.Width))

#       Species value
# 1      setosa   0.1
# 2      setosa   0.2
# 3      setosa   0.2
# 4      setosa   0.3
# 5      setosa   0.6
# 6  versicolor   1.0
# 7  versicolor   1.2
# 8  versicolor   1.3
# 9  versicolor   1.5
# 10 versicolor   1.8
# 11  virginica   1.4
# 12  virginica   1.8
# 13  virginica   2.0
# 14  virginica   2.3
# 15  virginica   2.5

ここで、「fivenum」関数はリストを返すため、種ごとに5行のエントリが作成されます。それが「fivenum」関数が私たちと戦っている部分です。

手順2:ラベル列を追加します。テューキーの5つの数値がわかっているので、「fivenum」関数がそれらを返す順序でそれらを呼び出すだけです。リストは、データの最後に到達するまで繰り返されます。

Tukeys_five <- c("Min","Q1","Med","Q3","Max") 
data$label <- Tukeys_five

#       Species value label
# 1      setosa   0.1   Min
# 2      setosa   0.2    Q1
# 3      setosa   0.2   Med
# 4      setosa   0.3    Q3
# 5      setosa   0.6   Max
# 6  versicolor   1.0   Min
# 7  versicolor   1.2    Q1
# 8  versicolor   1.3   Med
# 9  versicolor   1.5    Q3
# 10 versicolor   1.8   Max
# 11  virginica   1.4   Min
# 12  virginica   1.8    Q1
# 13  virginica   2.0   Med
# 14  virginica   2.3    Q3
# 15  virginica   2.5   Max

ステップ3:ラベルを配置したら、「reshape2」パッケージの「dcast」関数を使用して、このデータを新しい形状にすばやくキャストできます。

library(reshape2)
dcast(data, Species ~ label)[,c("Species",Tukeys_five)]

#      Species Min  Q1 Med  Q3 Max
# 1     setosa 0.1 0.2 0.2 0.3 0.6
# 2 versicolor 1.0 1.2 1.3 1.5 1.8
# 3  virginica 1.4 1.8 2.0 2.3 2.5

'dcast'関数は自動的にアルファベット順に並べ替えるため、最後のジャンクはすべて列の順序を指定するだけです。

お役に立てれば。

更新:他に利用できるオプションが1つあることに気付いたので、戻ることにしました。データフレーム定義の一部としていつでも行列をバインドできるため、次のように「集計」関数を解決できます。

data <- aggregate(Petal.Width ~ Species, iris, function(x) summary(fivenum(x))) 
result <- data.frame(Species=data[,1],data[,2])

#      Species Min. X1st.Qu. Median Mean X3rd.Qu. Max.
# 1     setosa  0.1      0.2    0.2 0.28      0.3  0.6
# 2 versicolor  1.0      1.2    1.3 1.36      1.5  1.8
# 3  virginica  1.4      1.8    2.0 2.00      2.3  2.5
于 2013-02-07T19:22:52.883 に答える
0

これが私の解決策です:

ddply(iris, .(Species), summarize, value=t(fivenum(Petal.Width)))
于 2015-10-04T22:55:54.627 に答える