59

The issue I believe is how CurrentDay is entered. It was previously created as:

Transaction <- function(PnL, Day)
  results <- list(a = PnL, b = Day)
  return(results)

Both PnL and Day are numeric values.

Day <- Transaction(PnL, Day)["b"]

Where Transaction returned a list and b is an integer.

moving_avg <- function(StockData, MA, CurrentDay){
  #MA = Days long the MA is
  #CurrentDay = What day we are currently on
  MAValue <- NULL
  total <- 0
  start <- CurrentDay - MA
  for(i in 1:length(MA)) {
    total <- total + StockData[[start, 4]]
    start <- start + 1
  }
  MAValue <- total/MA
  return(MAValue)
}

Anyone know why I am receiving this error?

Error in CurrentDay - MA : non-numeric argument to binary operator

BenLar
  • 609
  • 1
  • 6
  • 7
  • 2
    Please include sample data and show exactly how you are calling the function. See [how to make a reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). – MrFlick Apr 16 '15 at 04:42
  • 1
    The function's ok, you probably called it with non-numeric argument. Please provide a reproducible sample, like @MrFlick said. – smci Apr 16 '15 at 04:44
  • 1
    I think I found the issue, CurrentDay is being imputed from a variable I designated from a list. When I just print CurrentDay I get $b [1] 41 – BenLar Apr 16 '15 at 04:53

2 Answers2

86

Because your question is phrased regarding your error message and not whatever your function is trying to accomplish, I will address the error.

- is the 'binary operator' your error is referencing, and either CurrentDay or MA (or both) are non-numeric.

A binary operation is a calculation that takes two values (operands) and produces another value (see wikipedia for more). + is one such operator: "1 + 1" takes two operands (1 and 1) and produces another value (2). Note that the produced value isn't necessarily different from the operands (e.g., 1 + 0 = 1).

R only knows how to apply + (and other binary operators, such as -) to numeric arguments:

> 1 + 1
[1] 2
> 1 + 'one'
Error in 1 + "one" : non-numeric argument to binary operator

When you see that error message, it means that you are (or the function you're calling is) trying to perform a binary operation with something that isn't a number.

EDIT:

Your error lies in the use of [ instead of [[. Because Day is a list, subsetting with [ will return a list, not a numeric vector. [[, however, returns an object of the class of the item contained in the list:

> Day <- Transaction(1, 2)["b"]
> class(Day)
[1] "list"
> Day + 1
Error in Day + 1 : non-numeric argument to binary operator

> Day2 <- Transaction(1, 2)[["b"]]
> class(Day2)
[1] "numeric"
> Day2 + 1
[1] 3

Transaction, as you've defined it, returns a list of two vectors. Above, Day is a list contain one vector. Day2, however, is simply a vector.

Richard Border
  • 3,209
  • 16
  • 30
  • looking at my code, is my Day variable not a numeric value based on how it is originally set at the beginning? If not, what must I do to make it one? – BenLar Apr 16 '15 at 14:46
  • 1
    I have a similar problem, only I’m getting it when trying to join to plots (a boxplot and a jitterplot) that run fine separately. My error message reads ‘Error in p + o : non-numeric argument to binary operator’. Should I create a separate question for this, or is this something that should be discussed here in the comments? – Canned Man Dec 02 '16 at 08:31
  • 1
    @CannedMan this is largely unrelated but easy to fix. If you are trying to put them next to each other use `par(mfrow = c(1,2)` or `par(mfrow = c(2,1)`. Else call the first plot and then use `points()` or the like – Richard Border Jul 19 '17 at 18:05
  • "R only knows how to apply + (and other binary operators, such as -) to numeric arguments" - tiny caveat: except in ggplot (& ggmap etc) pipes, where "+" is used like the %>% pipe. – dez93_2000 Oct 28 '21 at 02:46
  • @dez93_2000 true! – Richard Border Oct 29 '21 at 13:45
1

If you run this before your code, everything is gonna be OK.

'+' <- function(e1, e2) {
  if (is.character(e1) | is.character(e2)) {
    paste0(e1, e2)
  } else {
    base::`+`(e1, e2)
  }
}
Heaven
  • 118
  • 1
  • 9