在R函数中使用过滤器

问题描述 投票:0回答:1

我有按季度划分的设备组件成本数据集。由于某些组件的价格按季度变化,而其他组件则按年变化。由于我需要按季度计算设备的总物料清单,因此我需要将所有Year数据集标准化为Quarter-Year

年份数据集示例。数据为宽格式。

df <- data.frame(Item = c("A", "B", "C"), 
                 Year2022 = c(2, 3, 8),
                 Year2023 = c(2, 4, 7.8),
                 Year2024 = c(3, 4, 7)) 

通常这就是我所做的:

  1. 定义想要的QY
  2. 将年份数据转换为长格式
  3. 重复年份栏 4 次
  4. 通过在前面添加数字来改变 QY 列(1Q22、2Q22 等)
  5. 过滤数据集以仅显示想要的 QY
#define QY that I wanted
QY_level <-  c("1Q22", "2Q22", "3Q22", "4Q22",
               "1Q23", "2Q23", "3Q23", "4Q23",
               "1Q24")

df_nofunc <- df %>%
  pivot_longer(2:4,
               names_to = "QY",
               values_to = "Values") %>%
  slice(rep(1:n(), each = 4L)) %>%
  mutate(QY = paste0(1:4, "Q", str_extract(QY, "[0-9]{2}$"))) %>%
  filter(QY %in% QY_level)

这工作得很好,但我了解到使用函数是一种更好的方法,特别是因为我不断在我的项目中复制和粘贴相同的代码。我想尝试将其构建为函数形式,但过滤器不起作用。

我知道有类似的问题,但我不太明白为什么它不起作用,只知道我需要使用 sym() 将 QY 列转换为变量,然后使用 !! 在过滤器内取消引用它(嘭嘭)。但还是没成功。

generate_QY <- function(x) {
  x %>%
    pivot_longer(2:4,
                 names_to = "QY",
                 values_to = "Values") %>%
    slice(rep(1:n(), each = 4L)) %>%
    mutate(QY = paste0(1:4, "Q", str_extract(QY, "[0-9]{2}$"))) %>% 
    filter(!!sym(QY) %in% QY_level)
  
  return(x)
}


df_withfunc <- generate_QY(df)

它仍然说未找到对象“QY”。为什么它不起作用以及如何让它起作用?

r dplyr
1个回答
0
投票

您需要在函数中稍微更改您的

filter

generate_QY <- function(x) {
  x <- x %>%
    pivot_longer(2:4,
                 names_to = "QY",
                 values_to = "Values") %>%
    slice(rep(1:n(), each = 4L)) %>%
    mutate(QY = paste0(1:4, "Q", str_extract(QY, "[0-9]{2}$"))) %>% 
    filter(!!sym("QY") %in% QY_level) # Here! 
  
  return(x)
}

> generate_QY(df)
# A tibble: 27 × 3
   Item  QY    Values
   <chr> <chr>  <dbl>
 1 A     1Q22       2
 2 A     2Q22       2
 3 A     3Q22       2
 4 A     4Q22       2
 5 A     1Q23       2
 6 A     2Q23       2
 7 A     3Q23       2
 8 A     4Q23       2
 9 A     1Q24       3
10 B     1Q22       3
© www.soinside.com 2019 - 2024. All rights reserved.