使用列表减少R中的代码重复

5us2dqdw  于 2023-05-11  发布在  其他
关注(0)|答案(1)|浏览(118)

背景:

大家好,
我希望你能帮助我把我的理解和代码到一个新的水平。我正试图让我的头脑围绕列表,它们的好处,以及使用它们来减少冗余代码。尽管我在网上阅读了很多关于名单和申请家庭的信息,但我仍然不明白如何在日常工作中实施。
这里有一种情况,我想可以大大简化-这是我经常写的代码类型,我希望用更简洁的格式来取代。

示例:

让我们假设整个mtcars数据是一个单一的观察年-比如2018年。假设我们有2000年以前的数据。因此,现在有“18”个mtcars data. frame,其中一个年份列表示年份,我们将18个观察结果按行绑定到单个data. frame中。这是我现在正在处理的数据类型的一个示例。按年份分开的观察结果。

data <- mtcars %>%
group_by(date) %>%
  mutate(rank = dense_rank(desc(mpg))
         ))

我想简化的数据操作:

  • 过滤:我想过滤所有给定的一年由不同的mpg排名

data %>% filter(gear == 4,date == '2005')%>% filter(rank %in% c(1:5))
data %>% filter(gear == 4,date == '2005')%>% filter(rank %in% c(6:10))
数据%>% filter(齿轮== 4,日期== '2005')%>% filter(排名%在% c(11:15))
简化上面冗余代码块的最佳方法是什么?
例如,我想使用seq函数并沿着以下方式执行一些操作:

data %>% 
filter(gear == 4, date == '2005') %>%
filter(rank %in% seq(1, 100, by = 5))

并将每个等级组的输出存储到列表中,然后在GGPlot中绘制所有这些列表。

55ooxyrt

55ooxyrt1#

学习以整洁的方式使用列表和列表列可能有点复杂。Jenny Bryan的purrrtutorial。在这里,您试图避免需要为yeargearrank的不同值多次执行filter行。有几个步骤:
1.弄清楚如何获得所需值的所有组合。我们在这里使用purrr::cross_df来实现这一点,这是一种非常方便的获取变量组合的方法。
1.实际运行每个组合的操作。因为我们的数据现在已经很好地设置为每行都是一组输入,所以我们可以使用pmap将每个过滤后的数据集存储为列表元素。根据我们想要的绘图,我们可以使用其他工具,如unnest,将数据转换为我们想要绘制的格式。
我希望这可以说明,一般来说,如果你意识到你做了太多次,基本上有两个步骤;创建一个或多个可以迭代的列表,并使用map函数对每个列表元素应用所需的操作。

library(tidyverse)
data <- mtcars %>%
  bind_rows(
    mtcars %>% mutate(year = 2005),
    mtcars %>% mutate(year = 2006)
    ) %>% 
  group_by(year) %>%
  mutate(rank = dense_rank(desc(mpg)))

combos <- cross_df(list(
  year = 2005:2006,
  gear = 3:5,
  start = seq(1, 100, by = 5)
  ))

combos %>%
  mutate(
    rank_range = map(start, ~ .x:(.x + 4)),
    filtered = pmap(
      .l = list(year, gear, rank_range),
      .f = ~ data %>%
        filter(gear == ..2, year == ..1) %>%
        filter(rank %in% ..3)
        )
    )
#> # A tibble: 120 x 5
#>     year  gear start rank_range filtered         
#>    <int> <int> <dbl> <list>     <list>           
#>  1  2005     3     1 <int [5]>  <tibble [0 x 13]>
#>  2  2006     3     1 <int [5]>  <tibble [0 x 13]>
#>  3  2005     4     1 <int [5]>  <tibble [4 x 13]>
#>  4  2006     4     1 <int [5]>  <tibble [4 x 13]>
#>  5  2005     5     1 <int [5]>  <tibble [2 x 13]>
#>  6  2006     5     1 <int [5]>  <tibble [2 x 13]>
#>  7  2005     3     6 <int [5]>  <tibble [2 x 13]>
#>  8  2006     3     6 <int [5]>  <tibble [2 x 13]>
#>  9  2005     4     6 <int [5]>  <tibble [6 x 13]>
#> 10  2006     4     6 <int [5]>  <tibble [6 x 13]>
#> # ... with 110 more rows

reprex package(v0.2.0)于2018-05-14创建。

相关问题