如何使用dplyr语法在R中编写循环"for"循环

Naj*_*j S 6 loops r dplyr

我有一个广泛的代码块,我在R中使用dplyr语法编写.但是,我试图将该代码放在一个循环中,这样我最终可以创建多个输出文件而不是一个.不幸的是,我似乎无法这样做.

为了说明我的问题,让我们参考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"
Run Code Online (Sandbox Code Playgroud)

让我们说我想保存物种"杂色"的平均Petal.Length.dplyr代码可能如下所示:

    MeanLength2 <- iris %>% filter(Species=="versicolor")
                       %>% summarize(mean(Petal.Length)) %>% print()
Run Code Online (Sandbox Code Playgroud)

哪个会给出以下价值:

      mean(Petal.Length)
    1               4.26
Run Code Online (Sandbox Code Playgroud)

让我们尝试创建一个循环来获得所有物种的平均花瓣长度.

从我对循环的了解很少,我想做这样的事情:

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

出于某种原因,我必须在循环内指定数据框和列,在使用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"  
Run Code Online (Sandbox Code Playgroud)

因此代码输出3.758三次,这是数据集中所有物种的平均花瓣长度.这表示"过滤器"代码未按预期工作.据我所知,似乎循环本身按预期运行,因为所有三个独特的物种名称都在最终输出中打印出来.

如何使用for循环来做这样的事情?我知道这个特殊的练习不需要使用花式循环,因为通过使用例如dplyr中的"group_by"函数可以轻松获得所有物种的平均花瓣长度,但我希望输出接近于100个独特的表格和PDF文件与我正在使用的数据集以及知道如何使用for循环真的有助于此目的.

jor*_*ran 6

正如我在评论中提到的,如果你真的需要将结果分开,那么可能更容易使用group_by,然后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
Run Code Online (Sandbox Code Playgroud)


don*_*lek 6

不幸的是,您的代码没有引发任何错误。如果你一行一行地运行你的代码,你就会明白我在说什么。对于这个例子,我将选择循环的第一次迭代,让我们替换i"setosa"

> 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)
Run Code Online (Sandbox Code Playgroud)

你的过滤器产生一个没有观察的数据框,所以继续下去没有意义,但对于这个例子,让我们运行其余的代码:

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

发生的事情是您iris从代码中调用数据集,一个更明显的例子是:

> filter(iris, iris$Species == unique(iris$Species)["setosa"]) %>% 
+ summarize(mean(mtcars$cyl))
  mean(mtcars$cyl)
1           6.1875
Run Code Online (Sandbox Code Playgroud)

这就是为什么您没有得到预期的答案、您的过滤器不起作用并且您从另一个数据集中获得了汇总统计数据的原因。

正如 TJ Mahr 提到的,您的代码没有指定数据集运行良好:

> 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"
Run Code Online (Sandbox Code Playgroud)

我希望这有帮助