首页 > 解决方案 > 忽略 R 函数中的错误 - try() 函数不起作用

问题描述

我有一个带有各种 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”语句中,但必须有一种更简单的方法。

标签: rerror-handling

解决方案


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

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")

推荐阅读