编写R函数以支持向量

时间:2015-09-29 20:34:40

标签: r function vector

我有这个功能:

pcal.getPeriodForDate <- function(date_) {
    dateObject <- as.POSIXlt(date_)
    calendarStart <- pcal.getCalendarStart(dateObject$year + 1900)

    difference <- dateObject - calendarStart

    if(difference < 0) {
        calendarStart <- pcal.getCalendarStart(dateObject$year + 1899)
        difference <- dateObject - calendarStart
    }

    period <- difference / 28

    week <- ifelse(period < 1, ceiling(period * 4), ceiling((period - floor(period)) * 4))

    return(list(Period = as.numeric(ceiling(period)), Week = week))
}

我还有一个具有以下结构的数据框

> str(sells)
'data.frame':   73738 obs. of  4 variables:
 $ LOC_NBR: chr  "2" "2" "2" "2" ...
 $ SLS_DT : Date, format: "2015-02-01" "2015-02-02" "2015-02-03" "2015-02-04" ...
 $ SALES  : num  1 2 3 4 5 ...

我希望能够做到这一点:

sells$pd <- pcal.getPeriodForDate(sells$SLS_DT)$Period
然而,我收到了很多警告:

Warning messages:
1: In if (year < 2000) { :
  the condition has length > 1 and only the first element will be used
2: In seedYear:year :
  numerical expression has 73738 elements: only the first used
3: In if (difference < 0) { :
  the condition has length > 1 and only the first element will be used
4: In if (year < 2000) { :
  the condition has length > 1 and only the first element will be used
5: In seedYear:year :
  numerical expression has 73738 elements: only the first used

该函数可正常传递一个值:

> pcal.getPeriodForDate('2015-09-29')
$Period
[1] 9

$Week
[1] 3

我该如何做到这一点?

1 个答案:

答案 0 :(得分:2)

函数if在R中没有矢量化,这意味着你只能使用长度为1的向量。使用带有更大向量的if将导致你得到的警告,这是一个非常严重的警告这不应该被忽略,因为if只使用向量的第一个元素,这很可能会给你带来麻烦。看到这个简单的案例:

> if(c(1,-5,3) > 0) print('hello')
[1] "hello"
Warning message:
In if (c(1, -5, 3) > 0) print("hello") :
  the condition has length > 1 and only the first element will be used

在这种情况下,虽然-5上面的向量中存在hello,但仅因为if检查向量的第一个元素而返回。

为了将if与向量一起使用,您有三个选项:

所有

当您希望向量的每个元素确认条件时,将其与函数all一起使用:

if( all(c(1,-5,3) > 0) ) print('hello')
#this does not return anything

任何

如果您希望至少有一个元素确认条件,请将其与函数any一起使用:

> if( any(c(1,-5,3) > 0) ) print('hello')
[1] "hello"

申请家庭

当你需要一个与支票(c(1,-5,3)这里)相同尺寸的矢量时,将它与* apply系列一起使用,其中每个元素将根据条件进行检查:

> vapply(c(1,-5,3), function(x) {
   if (x > 0) 'Hello' else NA_character_
 }, 
 character(1))
[1] "Hello" NA      "Hello"

我无法运行您的功能告诉您上面需要哪个版本,因为我不知道difference的使用方式或pcal.getCalendarStart的用途,但这应该足以帮助您修复警告你得到。根据您的行为方式使用上述方法之一,您不应该收到任何警告。