2016-09-01 11 views
4

Rのdplyr構文を使用して書いた広範なコードブロックがあります。しかし、私はそのコードをループに入れようとしています。最終的には1つではなく複数の出力ファイルを作成することができます。残念ながら、私はそうすることができないようです。私の問題についての説明の目的のためにdplyr構文を使用してRのループ "for"ループを書く方法

は、のは、Rで一般的に使用される「アイリス」のデータセットを参照してくださいしてみましょう:

 > data("iris") 
     > str(iris) 
     'data.frame': 150 obs. of 5 variables: 
     $ Sepal.Length: num 
     $ Sepal.Width : num 
     $ Petal.Length: num 
     $ Petal.Width : num 
     $ Species  : Factor w/ 3 levels "setosa","versicolor","virginica" 

のは、私は種「カワラタケ」の平均Petal.Lengthを保存したいとしましょう。 dplyrコードは、次のようになります。次の値を与えるだろう

MeanLength2 <- iris %>% filter(Species=="versicolor") 
         %>% summarize(mean(Petal.Length)) %>% print() 

 mean(Petal.Length) 
    1    4.26 

は、種のすべての平均花びらの長さを取得するためのループを作成しようとします。

少し私がループで知っているから、私はこのような何かしたいと思う:何らかの理由で

 for (i in unique(iris$Species)) 
     { 
     iris %>% filter(iris$Species==unique(iris$Species)[i]) %>% 
     summarize(mean(iris$Petal.Length)) %>% print() 
     print(i) 
     } 

を、私は一般的ではありませんこれは、データフレームとループ内の列を指定する必要がありましたケースはdplyrの配管機能を使用しています。私はこれが問題の指標であると仮定しています。

とにかく、上記のコードは、次の出力を与える:

  mean(iris$Petal.Length) 
    1     3.758 
    [1] "setosa" 
      mean(iris$Petal.Length) 
    1     3.758 
    [1] "versicolor" 
      mean(iris$Petal.Length) 
    1     3.758 
    [1] "virginica" 

ように、コードは、データセット内のすべての種全体の平均花弁長で3.758 3回出力しています。これは、「フィルター」コードが期待通りに機能しなかったことを示します。私が知ることから、3つの固有のすべての種名が最終的な出力に印刷されたので、ループ自体が意図したとおりに機能しているように見えます。

forループを使用してこのようなことを行うにはどうすればよいですか?この特定のエクササイズでは、例えばdplyrの "group_by"関数を使って、すべての種の平均花弁長を簡単に得ることができるので、ファンシーループを使う必要はないと理解していますが、私が作業しているデータセットを持つ100個のユニークなテーブルとPDFファイルと、forループの使い方を知ることは、その目的に本当に役立ちます。私はあなたが本当に結果が分離が必要な場合、おそらくちょうどgroup_byを使用する方が簡単になります、私のコメントで述べたように

+0

に役立ちます願っています ' group_by'を作成し、結果をあなたが望むそれぞれの要素の要素を持つリストに 'split()'します。 – joran

+0

下記のコードをありがとう。私のデータセットは、私がこの質問のために参照した虹彩データよりも複雑ですが、私はあなたのお勧めのワークフローを利用して私が意図したことをすることができると信じています。 –

+0

forループの内部は 'iris%>%filter(Species == i)%>%summarize(平均(Petal.Length))%>%print()'でなければなりません。それはそれが各種のために異なる数を生産するようにします。 –

答えて

5

、その後split()結果:

iris %>% 
    group_by(Species) %>% 
    summarise(mn = mean(Petal.Length)) %>% 
    split(.,.$Species) 

$setosa 
# A tibble: 1 × 2 
    Species mn 
    <fctr> <dbl> 
1 setosa 1.462 

$versicolor 
# A tibble: 1 × 2 
    Species mn 
     <fctr> <dbl> 
1 versicolor 4.26 

$virginica 
# A tibble: 1 × 2 
    Species mn 
    <fctr> <dbl> 
1 virginica 5.552 
3

あなたのコードがなかったことを残念ですエラーを起こす。コードを1行ずつ実行すると、私が何を言っているのか理解できます。この例では、私は、あなたのループの最初の反復を選ぶのが"setosa"ためiに代わっます:

> iris %>% filter(iris$Species == unique(iris$Species)["setosa"]) 
[1] Sepal.Length Sepal.Width Petal.Length Petal.Width Species  
<0 rows> (or 0-length row.names) 

あなたのフィルタが無い観測とデータフレームを生成しないので、先に行くにはポイントが、この例のために、実行してみましょう残りのコード:

> filter(iris, iris$Species == unique(iris$Species)["setosa"]) %>% 
+ summarize(mean(mtcars$cyl)) 
    mean(mtcars$cyl) 
1   6.1875 
012:

> iris %>% filter(iris$Species == unique(iris$Species)["setosa"]) %>% 
+ summarize(mean(iris$Petal.Length)) 
    mean(iris$Petal.Length) 
1     3.758 

何が起こったのは、あなたがより多くの明白な例は以下のようになり、あなたのコード内からirisデータセットを呼んでいるということです

これは、あなたが期待した答えを得られず、フィルタが機能せず、別のデータセットから要約統計量が得られた理由です。

TJマール社が述べたように、データセットを指定せずに、あなたのコードは正常に動作:

> for (i in unique(iris$Species)) 
+ { 
+  iris %>% filter(Species==i) %>% 
+   summarize(mean(Petal.Length)) %>% print() 
+  print(i) 
+ } 
    mean(Petal.Length) 
1    1.462 
[1] "setosa" 
    mean(Petal.Length) 
1    4.26 
[1] "versicolor" 
    mean(Petal.Length) 
1    5.552 
[1] "virginica" 

私はあなたが本当にグループごとに別々のオブジェクトが必要な場合、おそらく使用する方が簡単だろう、これは

関連する問題