IF ELSE Generator基于值

时间:2019-11-17 09:45:36

标签: r dplyr

我有一个数据框,其中包含Region,minage和maxage列中的其他条件。参见下面的df。

   Seasoning Region minage maxage
1 mths:36-47      A     36     47
2 mths:24-35      A     24     35
3 mths:12-23      A     12     23
4 mths:36-47      B     36     47
5 mths:24-35      B     24     35
6 mths:12-23      B     12     23

我想在函数内以自动化方式生成以下IF ELSE条件,因为我的实际数据集中有40-50个以上的条件。简而言之,我不想手动输入其他条件。 if条件的格式-

(seasoning >= minage) & (seasoning <= maxage) & (Region == value_Region_column)

功能

bx_is <- function(seasoning = NULL, Region = NULL) {
  Bx = if ((seasoning >= 36) & (seasoning <= 47) & (Region == 'A')) {trans1} 
  else if ((seasoning >= 24) & (seasoning <= 35) & (Region == 'A')) {trans2}
  else if ((seasoning >= 12) & (seasoning <= 23) & (Region == 'A')) {trans3}
  else if ((seasoning >= 36) & (seasoning <= 47) & (Region == 'B')) {trans4}
  else if ((seasoning >= 24) & (seasoning <= 35) & (Region == 'B')) {trans5}
  else if ((seasoning >= 12) & (seasoning <= 23) & (Region == 'B')) {trans6}
  return(data.matrix(Bx))
}

bx_is(seasoning=28, Region = 'B')

输入Df

mx = structure(list(Seasoning = structure(c(3L, 2L, 1L, 3L, 2L, 1L
), .Label = c("mths:12-23", "mths:24-35", "mths:36-47"), class = "factor"), 
Region = structure(c(1L, 1L, 1L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor"), 
minage = c(36L, 24L, 12L, 36L, 24L, 12L), maxage = c(47L, 35L, 23L, 47L, 35L, 23L)), 
class = "data.frame", row.names = c(NA, -6L))

注意在上面显示的bx_is()函数中,trans1 ... trans6是6个不同的矩阵。我想在22M迭代的循环中基于此函数的条件使用矩阵。 我无法应用过滤器,因为它需要一些处理并且会降低22M迭代的速度。

1 个答案:

答案 0 :(得分:0)

以下是使用dplyr软件包的解决方案:

library(dplyr)

df = mx %>% mutate(res=paste0("trans", row_number()))

bx_is <- function(seasoning, region) {
  r = df %>% filter(Region == region, minage <= seasoning, maxage >= seasoning)
  get(r$res)
}

它将创建一个数据帧df,该数据帧将附加一个与结果对应的res列,以针对每个条件(行)输出。

函数bx_is根据条件过滤数据帧,并为符合条件的行输出res值。

编辑 由于它(甚至在使用data.table时)也比使用if else语句要慢,所以我们可以生成相同的代码并使用以下代码对其求值:

f <- function() {
  s = "bx_is <- function(seasoning = NULL, Region = NULL) {"

  for (i in 1:dim(df)[1]) {
    r = paste0("((seasoning >= ",
               df[i, ]$minage,
               ") & (seasoning <= ",
               df[i, ]$maxage,
               ') & (Region == "',
               df[i, ]$Region,
               '")) {',
               df[i, ]$res,
               "}")
    if (i == 1) {
      s = paste0(s, " Bx = if ", r)
    } else {
      s = paste0(s, "\n else if ", r)
    }
  }

  s = paste0(s, "\n return(data.matrix(Bx))}")
  s
}
eval(parse(text=f()))