首页 文章

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

提问于
浏览
5

我有一个广泛的代码块,我在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"

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

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

哪个会给出以下 Value :

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

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

2 回答

  • 5

    正如我在评论中提到的,如果你真的需要将结果分开,那么使用 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
    
  • 3

    遗憾的是,你的代码没有理解'm saying. For this example I will choose the first iteration of your loop, let'替换 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)
    

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

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

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

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

    这就是为什么你没有得到你期望的答案,你的过滤器不起作用,你从另一个数据集得到一个摘要统计 .

    正如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"
    

    我希望这有帮助

相关问题