首页 > 解决方案 > 如何编写依赖于常数的动态方程

问题描述

我正在尝试编写一个取决于常数(级别数)的方程式。如下所示,如果我有 2 个级别,if 语句将引用 L1 和 L2。

问题:

  1. 如何修改代码以反映 x 个级别?x 可以是任何整数(通常是 2-12)。
  2. 如何在没有 for 循环的情况下重写代码?

非常感谢你的帮助!

例如(对于 2 个级别):

查找表

L1_var <- c("Price", "Price", "Price", "Price")
L1_val <- c("AO", "AO", "Premium", "Premium")

L2_var <- c("Type", "Type", "Form", "Form")
L2_val <- c("Diet", "Regular", "Bottle", "Can")

tbl <- data.frame(L1_var, L1_val, L2_var, L2_val)

数据集

Price <- c("Premium", "AO", "AO")
Type  <- c("Diet", "Regular", "Diet")
Form  <- c("Bottle", "Bottle", "Can")

df <- data.frame(Price, Type, Form)

对于 num_level = 2

for (i in 1:nrow(df)) {
  for (j in 1:nrow(tbl)) {
    if (df[i, tbl$L1_var[j]] == tbl$L1_val[j] & 
        df[i, tbl$L2_var[j]] == tbl$L2_val[j]) {
      df[i, "L1"] <- paste0(tbl$L1_var[j], ": ", tbl$L1_val[j])
      df[i, "L2"] <- paste0(tbl$L2_var[j], ": ", tbl$L2_val[j])
    }
  }
}

如果我在 df 中有 3 个级别,我希望代码为:

for (i in 1:nrow(df)) {
  for (j in 1:nrow(tbl)) {
    if (df[i, tbl$L1_var[j]] == tbl$L1_val[j] & 
        df[i, tbl$L2_var[j]] == tbl$L2_val[j] &
        df[i, tbl$L3_var[j]] == tbl$L3_val[j] ) {
       
      df[i, "L1"] <- paste0(tbl$L1_var[j], ": ", tbl$L1_val[j])
      df[i, "L2"] <- paste0(tbl$L2_var[j], ": ", tbl$L2_val[j])
      df[i, "L3"] <- paste0(tbl$L3_var[j], ": ", tbl$L3_val[j])
    }
  }
}

标签: rfor-loop

解决方案


这是我解决问题的方法,大量使用purrrand dplyr。它应该适用于任何数量的变量tbl

library(purrr)
library(dplyr)

tbl %>%
  pmap(function(...) {
    args <- c(...)
    vars <- args[seq(1, length(args), 2)] %>%
      set_names(NULL)
    values <- args[seq(2, length(args), 2)] %>%
      set_names(vars)
    df %>%
      filter(across(vars, ~ . == values[cur_column()])) %>%
      mutate(across(.cols = vars,
                    .fns = ~ sprintf("%s: %s", cur_column(), .),
                    .names = "L{which(vars ==.col)}"))
  }) %>%
  bind_rows()

推荐阅读