Error using next in for loop R

可紊 提交于 2020-04-16 02:06:10

问题


I keep getting this error in my For loop:

Error in FUN(X[[i]], ...) : no loop for break/next, jumping to top level

autoAnal <- function(x){  
    if(!is.numeric(x)){  
        next  
    }  
    m <- median(x, na.rm = T)  
    a <- mean(x, na.rm = T)  
    s <- sd(x, na.rm = T)  
    q <- quantile(x, na.rm = T)  
    q3 <- q[4]  
    q1 <- q[2]  
    outhigh <- (1.5 * q3) + IQR(x, na.rm = T)  
    outlow <- (1.5 * q1) - IQR(x, na.rm = T)    
    data.table(Median = m, Average = a, StDev = s,   
    Outhigh = outhigh, Outlow = outlow)  
}  

Channel Data
Channel june july december
ATM 666 783 333
VISA 893 321 321
DEBIT 931 134 123
MERCHANT 913 111 134

The first varible - "Channel" is not numerical, so I want R to skip and go to the next variable. However, I get the error above. I can run the function successfully on a numerical vector, but when I use a dataframe or data.table it doesn't work. When I run this code I get the error:

test <- lapply(channnel, autoAnal)   

What am I doing wrong with the 'next' statement in my for loop?

Thank you.


回答1:


In order to understand why next doesn't work, we have to break down the two parts of your code that you've attempted. To do this, it makes more sense to work backwards and examine how lapply works. Let's start with a basic variable called i and set it equal to the numbers 1 through 10. Once we have that, we'll use lapply to see how the function handles an input vector.

i <- 1:10
tmp <- lapply(i, as.character)

If you run that code and look at tmp, you'll see that we get a list with 10 elements, where each element in the list is a single number stored as a string. What this should show you is that lapply works as a loop going through each element of an object that you've passed to it and feeding that into whatever function you've chosen. So let's use that to look at what your code is doing.

test <- lapply(channnel, autoAnal)

This is going to take the first element of channnel and pass it into your function autoAnal. At this point, the code switches from the loop that lapply is running and steps into a single function call. The first thing your function does is checks if the element that has been passed into the function is numeric or not. If it's not, you use next to tell R to skip that variable.

However, next only works in loops, such as while and for. So let's go back to our i variable. Let's say we wanted to loop over i and print a message if the number is even, otherwise, skip to the next number. We can do that like this:

for (i in 1:10) {
  if (i %% 2 == 0) {
    print("i is even!")
  } else {
    next
  }
}

In this instance, using next doesn't throw an error because it's used within a for loop. That's why in my comment I mentioned that there is no for loop, at least not where you think there is. My intention behind saying this was to point out that, yes, lapply is a loop, but not for the sake of what you're trying to do with next.

So, what if we just tried to use next with an if statement?

i <- 5
if (i %% 2 == 0) {
  print("i is even")
} else {
  next
}

This will throw an error because your code isn't a loop. There's just one interation that it's going to go through, which involves checking if i is even or not, and then moving on. Much in the same way that next doesn't work here, it's not working in your code because the if statement is just checking if the element passed to it is numeric. There's nothing for it to "next" to if that makes sense. For this reason, next is only used with loops.

In my opinion, next is never even really needed. You can always just use if/else statements to run code if needed or otherwise just ignore the variable. As an example, let's rewrite your code to take advantage of if/else and get rid of our next call.

autoAnal <- function(x){  
  if(is.numeric(x)){  
    m <- median(x, na.rm = T)  
    a <- mean(x, na.rm = T)  
    s <- sd(x, na.rm = T)  
    q <- quantile(x, na.rm = T)  
    q3 <- q[4]  
    q1 <- q[2]  
    outhigh <- (1.5 * q3) + IQR(x, na.rm = T)  
    outlow <- (1.5 * q1) - IQR(x, na.rm = T)    
    data.table(Median = m, Average = a, StDev = s,   
    Outhigh = outhigh, Outlow = outlow)
  } else {
    print("Skipping this element")
  }
}  

By using if/else, we tell the computer to only perform those calculations on variables if they're numeric. Otherwise, print a message saying we're skipping a variable. In normal code, I'd advise just dropping the else statement all together. lapply will naturally return NULL if there is no value returned, and the function will skip all of the code completely for the first variable since it's not numeric. In the end, you end up with an error-free function that only operates on numeric data.

Hopefully that helps illustrate why next doesn't work in your current context.



来源:https://stackoverflow.com/questions/34386892/error-using-next-in-for-loop-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!