0

I have this R function where i make some computations like average and median of such values comes from a website. fromTime and toTime are two dates in a string format like 2020-10-12. computationType is a string that specify the type of computation like average or median. new_suri is a serviceUri (string) and sensor is also a string. I have a problem in the second for (that is the same in the second part of the function) where i do this: Take the "i" element of value and add this element to another list called valori. After this check if there is some error in this "i" element. If some of the conditions in the if statement is met then remove the "i" element from valori. I would like the element to be deleted and then the list to return to its original length. The length I would have had without that element. But i obtain the error that you can see below

dayHour <- function(fromTime,toTime,dayOfTrend,computationType,new_suri,sensor){
  errorList <- list()
  valori <- vector(mode = "double")
  dayHourValues <- list()
  dayOTList <- list()
  hour <- c("00","01","02","03","04","05","06","07","08","09","10","11","12","13","14","15","16","17","18","19","20","21","22","23")
  interval <- as_date(ymd(fromTime):ymd(toTime)) # giorni presenti tra le due date "fromTime" e "toTime"
  for(a in 1:length(interval)) {
    if(strftime(interval[[a]], '%A') == dayOfTrend){
      element <- as.character.Date(interval[[a]])
      dayOTList <- c(dayOTList, element) # Lista dei giorni che servono per calcolare il trend in funzione del dayOfTrend (es. tutti i lunedì)
    }
  }
  
  for (j in 1:length(hour)) {
    if (j == 24){
      for (y in 1:length(dayOTList)) {
        from <- paste(hour[[j]],":00:00", sep = "")
        to <- paste(hour[[j]],":59:59", sep = "")
        fromDateTime <- paste(dayOTList[[y]],"T",hour[[j]],":00:00", sep = "") #yyyy-mm-ddThh:mm:ss
        toDateTime <- paste(dayOTList[[y]],"T",hour[[j]],":59:59", sep = "") #yyyy-mm-ddThh:mm:ss
        
        # Costruisco la query per ottenere i dati richiesti
        api <- paste("SERVICEURI",
                     new_suri,
                     "&valueName=",
                     sensor,
                     "&fromTime=",
                     fromDateTime,
                     "&toTime=",
                     toDateTime,
                     sep="")
        
        # Invio la chiamata e la parso sotto forma di JSON in res
        res <- fromJSON(api)
        
        # Prendo il blocco di valori che contiene quel sensore
        value <- res$realtime$results$bindings
        # Estrapolo il valore richiesto che si trova sotto il nome di sensor
        value <- getElement(value,sensor)
        
        
        for (i in 1:length(value)) {
          valori <- c(valori,as.numeric(value[[i]]))
          if (is.na(valori[[i]])){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value")
          }else if(is.null(valori[[i]])){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value")
          }else if(sensor == "averageSpeed" & valori[[i]] >= 130){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value")
          }else if(sensor == "concentration" & valori[[i]] >= 900){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value")
          }else if(sensor == "vehicleFlow" & valori[[i]] >= 900){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value", "\n")
          }else{
            print("All is ok!")
          }
        }
    valori <- valori[!str_detect(valori, pattern = "error")]
        
      }
      if(computationType == "average"){
        computedValues <- mean(valori) # calcolo la media dei valori nell'intervallo orario per ogni data presente nella lista
      }else{
        computedValues <- median(valori) # calcolo la mediana dei valori nell'intervallo orario per ogni data presente nella lista
      }
      valori <- vector(mode = "double") # pulisco la lista che deve contenere gli altri valori per una nuova fascia oraria
      dayHourValues <- c(dayHourValues,computedValues)
      computedValues <- list()
    }else{
      for (y in 1:length(dayOTList)) {
        from <- paste(hour[[j]],":00:00", sep = "")
        to <- paste(hour[[j+1]],":00:00", sep = "")
        fromDateTime <- paste(dayOTList[[y]],"T",from, sep = "") #Tyyyy-mm-ddThh:mm:ss
        toDateTime <- paste(dayOTList[[y]],"T",to, sep = "") #Tyyyy-mm-ddThh:mm:ss
        
        # Costruisco la query per ottenere i dati richiesti
        api <- paste("SERVICEURI=",
                     new_suri,
                     "&valueName=",
                     sensor,
                     "&fromTime=",
                     fromDateTime,
                     "&toTime=",
                     toDateTime,
                     sep="")
        
        # Invio la chiamata e la parso sotto forma di JSON in res
        res <- fromJSON(api)
        
        # Prendo il blocco di valori che contiene quel sensore
        value <- res$realtime$results$bindings
        # Estrapolo il valore richiesto che si trova sotto il nome di sensor
        value <- getElement(value,sensor) 
        
        for (i in 1:length(value)) {
          valori <- c(valori,as.numeric(value[[i]]))
          if (is.na(valori[[i]])){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value")
          }else if(is.null(valori[[i]])){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value")
          }else if(sensor == "averageSpeed" & valori[[i]] >= 130){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value")
          }else if(sensor == "concentration" & valori[[i]] >= 900){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value")
          }else if(sensor == "vehicleFlow" & valori[[i]] >= 900){
            valori[[i]] <- paste("error", sep = "")
            errorList <- c(errorList,"In this time span: ",dayOTList[[y]],":",from, " to ", to, " there is a wrong value", "\n")
          }else{
            print("All is ok!")
          }
        }
    valori <- valori[!str_detect(valori, pattern = "error")]

        
      }
      if(computationType == "average"){
        computedValues <- mean(valori) # calcolo la media dei valori nell'intervallo orario per ogni data presente nella lista
      }else{
        computedValues <- median(valori) # calcolo la mediana dei valori nell'intervallo orario per ogni data presente nella lista
      }
      valori <- vector(mode = "double") # pulisco la lista che deve contenere gli altri valori per una nuova fascia oraria
      dayHourValues <- c(dayHourValues,computedValues)
      computedValues <- list()
    }
  }
  
  return(returnList <- list("values" = dayHourValues, "error" = errorList)) # Ritorna lista dei 24 valori tipici 
}

And now i obtain this error:

Error in valori[[i]] <- NULL : replacement has length zero
In addition: Warning messages:
1: In if (is.na(value[[i]])) { :
the condition has length > 1 and only the first element will be used
2: In if (sensor == "averageSpeed" & value[[i]] >= 130) { :
the condition has length > 1 and only the first element will be used

Update: I solved the first problem, but now the problem is this:

[1] "All is ok!"
[1] "All is ok!"
[1] "All is ok!"
Error in valori[[i]] : 
  attempt to select less than one element in integerOneIndex

So i think that the problem is something like that

  • At least in base R, you can't delete a value from a list like that. Also, there are several other problems in your code. We can better help you if you give us a richer context. For instance, what are your `y`, `from` and `to`? They don't even exist in your for loop. If you call them like that, you will likely get the same repeated message for every iteration. – ekoam Nov 05 '20 at 17:03
  • Sorry, i edited the code. I want that when an element of the vector "valori" satisfy one of these condition then a line is added in errorList vector – Andrea Di Martino Nov 06 '20 at 09:58
  • We can hardly help you with such limited information. As we have no idea what `valori` looks like, nor can we know what is your `sensor`, `from`, `to` or `value`. Please read about [how to make a reproducible example](https://stackoverflow.com/q/5963269/10802499) and update your question with the necessary information for us to work on. – ekoam Nov 06 '20 at 10:43
  • Ok thanks, following the guidelines i edited the original question. – Andrea Di Martino Nov 06 '20 at 14:00

0 Answers0