忽略R函数中的错误-try()函数不起作用

时间:2019-01-07 16:19:10

标签: r error-handling

我有一个带有各种UTM源/介质的DataFrame,并且我想对其进行分段,因此例如对于UTM_source = 123和UTM_medium = ABC / BCD的行,我想分配名称“ 123ABC”。我有50多个这样的行,包含各种来源和媒介的许多组合,所有其他组合都以“其他”结尾。

问题是,当我想将值分配给不存在的组合时,会发生错误并使函数中断。为了使代码正常工作,我必须手动检查所有50多种组合,然后运行其余代码。

segment_my_DF <- function(DF) {

  DF$segment <- NA

  # segment based on source and medium  

  DF[!is.na(DF$UTMSource__c) & !is.na(DF$UTMMedium__c) & 
DF$UTMSource__c =="123" & DF$UTMMedium__c =="ABC", ]$segment = 
"123ABC"
  DF[!is.na(DF$UTMSource__c) & !is.na(DF$UTMMedium__c) & 
DF$UTMSource__c =="123" & DF$UTMMedium__c =="BCD", ]$segment = 
"123ABC"
  DF[!is.na(DF$UTMSource__c) & !is.na(DF$UTMMedium__c) & 
DF$UTMSource__c =="234" & DF$UTMMedium__c =="ABC", 
]$segment = "234ABC"
...
  # pack all the others
  DF[is.na(DF$segment), ]$segment = "OTHERS"

  return(DF)
}

比方说,我拥有的DataFrame没有任何带有UTM_Source ='123'和UTM_Medium ='ABC'的行。我收到的错误消息是:

Error in `$<-.data.frame`(`*tmp*`, "segment", value = "B2B") : 
  replacement has 1 row, data has 0 

我希望函数会更进一步,例如“ if”语句。我尝试在函数内部使用try()(同时带有()和{}括号):

segment_my_DF <- function(DF) {

DF$segment <- NA

  # segment based on source and medium  

try(
...
)

# pack all the others
  DF[is.na(DF$segment), ]$segment = "OTHERS"

  return(DF)
}

它使函数立即崩溃。我在调用函数时尝试使用try()(同时带有()和{}括号):

segmented_Marketing <- try({segment_my_DF(Rest)})

它也不起作用。我应该如何处理这个问题?我想到的一件事是将所有这50多个条件包装在50多个“ if”语句中,但是必须有一种更简单的方法。

1 个答案:

答案 0 :(得分:0)

我会写一个简单的函数来做到这一点。例如,

setIfAny <- function(condition, value) {
  if (any(condition))
    DF[condition, "segment"] <<- value
}

因为我使用了<<-超级赋值运算符,所以赋值发生在函数外部,因此您可以执行类似的操作

setIfAny(!is.na(DF$UTMSource__c) & !is.na(DF$UTMMedium__c) & 
         DF$UTMSource__c =="123" & DF$UTMMedium__c =="ABC", 
         "123ABC")

如果要避免超级分配,可以将DF传递到函数中并在最后返回:

modifyIfAny <- function(data, condition, value) {
   if (any(condition))
      data[condition, "segment"] <- value
   data
}

您将用作的

DF <- modifyIfAny(DF, 
               !is.na(DF$UTMSource__c) & !is.na(DF$UTMMedium__c) & DF$UTMSource__c =="123" & DF$UTMMedium__c =="ABC", 
               "123ABC")