Register now to learn Fabric in free live sessions led by the best Microsoft experts. From Apr 16 to May 9, in English and Spanish.
I have this problem only on the web app and not the desktop. I made an R visual to take in a time series (daily data) and produce a forecasting graph and table visual. When I publish the app on the web, I get the following error:
Error in as.POSIXlt.POSIXct(x, tz) : (converted from warning) unable to identify current timezone 'C': please set environment variable 'TZ'
The source code is pasted at the bottom, although it is a bit convoluted... I believe one of the function calls uses the as.POSIXct function to coerce a date object from a string, and the data given is in the form of "YYYY-MM-DD" so I'm not sure if it's the lack of a timestamp and timezone in the string that's giving it an error, maybe the function's call to receive the tz variable isn't returning anything meaningful because it works fine on desktop. I've even tried setting the tz variable and giving the extra tz parameters in some of the function calls. What can I do to resolve this weird error?
R forecasting script (graph):
### R Script used for displaying a graph containing 6-month forecast ### aggregated by day. # Libraries library('ggplot2') library('forecast') library('tseries') library('lubridate') Sys.setenv(TZ='EST') # Determine which column is the date column firstCol = dataset[1,1] secondCol = dataset[1,2] isFirstDate <- grepl("[0-9]+-[0-9]+-[0-9]+", toString(firstCol)) isSecondDate <- grepl("[0-9]+-[0-9]+-[0-9]+", toString(secondCol)) dateColumn <- 1 valuesColumn <- 2 if(!isFirstDate){ dateColumn <- 2 valuesColumn <- 1 } theDates <- data.frame(dataset[dateColumn]) names(theDates) <- c("date") theValues <- data.frame(dataset[valuesColumn]) names(theValues) <- c("values") dataset <- cbind(theDates, theValues) # Get information on dataset, create date sequence count <- nrow(dataset) firstdate = dataset$date[1] firstyear = as.double(substring(dataset$date[1], 1, 4)) lastdate = dataset$date[count] lastyear = as.double(substring(dataset$date[count], 1, 4)) dataset$date <- lubridate::ymd(substring(dataset$date, 1,10)) dataset <- dplyr::arrange(dataset, date) # Fill in the empty dates with zeros # Get base values i <- 2 x <- data.frame(dataset$values[1]) d <- data.frame(dataset$date[1]) names(x) <- c("values") names(d) <- c("date") # Loop through each value while(i <= count){ # Get current day, month values thisMonth <- substring(dataset$date[i],6,7) lastMonth <- substring(dataset$date[i-1],6,7) today <- substring(dataset$date[i],9,10) yesterday <- substring(dataset$date[i-1],9,10) # Add missing dates if applicable # Add as many days as differenced from last date entry if( ((as.numeric(yesterday) + 1) != as.numeric(today)) & (thisMonth == lastMonth)){ # How many days do we need to fill in? daysToFill <- as.numeric(today)-as.numeric(yesterday)-1 # Fill in the days while(daysToFill > 0){ # Add to new dataset zeroValue <- data.frame(0) names(zeroValue) <- c("values") x <- rbind(x, zeroValue) dateValue <- sprintf("%s-%s-%s",substring(dataset$date[i],1,4), thisMonth, toString(as.numeric(substring(dataset$date[i],9,10)) - daysToFill)) dateValue <- data.frame(as.character(as.Date(dateValue, tz = "EST"))) names(dateValue) <- c("date") d <- rbind(d, dateValue) # decrement the daysToFill counter daysToFill <- daysToFill - 1 } # Case when the first days of month are skipped } else if(thisMonth != lastMonth){ # Get amount of days to fill daysToFill <- as.numeric(today)-1 # Add each day missing while (daysToFill > 0){ # Append dataset zeroValue <- data.frame(0) names(zeroValue) <- c("values") x <- rbind(x, zeroValue) dateValue <- sprintf("%s-%s-%s",substring(dataset$date[i],1,4), thisMonth, as.character(daysToFill)) dateValue <- data.frame(as.character(as.Date(dateValue, tz = "EST"))) names(dateValue) <- c("date") d <- rbind(d, dateValue) daysToFill <- daysToFill - 1 } } # If no missing values exist, then continue and then add to original dataset i <- i + 1 } # Append the dataset, then sort by date dataset <- rbind(dataset, cbind(d,x)) dataset$date <- lubridate::ymd(dataset$date) dataset <- dplyr::arrange(dataset, date) #### Aggregate the Data (by day) #### # Get base values i <- 2 x <- data.frame(dataset$values[1]) d <- data.frame(dataset$date[1]) names(x) <- c("values") names(d) <- c("date") ptr <- 1 # update after transforming the dataset count <- nrow(dataset) # Loop through each value while(i <= count){ # Get current and previous months and years thisMonth <- substring(dataset$date[i],6,7) lastMonth <- substring(dataset$date[i-1],6,7) today <- substring(dataset$date[i],9,10) yesterday <- substring(dataset$date[i-1],9,10) # Compare month values, either greater or lower # Also compare year if( (today > yesterday) || (thisMonth != lastMonth)){ # Increment pointer ptr <- ptr + 1 # Add new row to Date representing new day de <- data.frame(dataset$date[i]) names(de) <- c("date") d <- rbind(d, de) # Add new row to Values representing new aggregate dx <- data.frame(dataset$values[i]) names(dx) <- c("values") x <- rbind(x, dx) # Otherwise, aggregate data } else if( today == yesterday){ x$values[ptr] <- x$values[ptr] + dataset$values[i] } # Finish loop, increment i i <- i + 1 } dataset <- cbind(d,x) # update after transforming the dataset count <- nrow(dataset) count dataset # Create time series object and forecasted ARIMA fit model y = ts(dataset$values, start=c(firstyear, yday(firstdate)), frequency=365) y <- tsclean(y) fit = forecast(auto.arima(y), 183) # Plot everything and format axis plot(fit, xaxt="n") a = seq(as.Date(firstdate, tz = "EST"), by="month", length=183 + count) axis(1, at = decimal_date(a), labels = format(a, "%Y %b %d"), cex.axis=0.6, ylab = 'value') abline(v = decimal_date(a), col='grey', lwd=0.5)
Solved! Go to Solution.
I figured it out. One of the library imports was breaking the whole code because it couldn't get a good time zone variable from the system. All I had to do was set the time zone before the library imports. I wish errors were easier to read and more informative on the web...
This solution didn't work for me but I found out how to avoid tripping up on lubridate's need for a timezone: First just take in the datetime column with as.POSIXct, then use lubridate, where useful, to calculate off of those values.
library('lubridate') dataset$Time <- as.POSIXct(dataset$Time,format="%Y-%m-%dT%H:%M:%OS") dataset$Time <- dataset$Time + minutes(5)
I think MS should better document the way the dataset is constructed. I suppose it's too late to always transfer datatime columns with POSIXct values instead of text values.
I figured it out. One of the library imports was breaking the whole code because it couldn't get a good time zone variable from the system. All I had to do was set the time zone before the library imports. I wish errors were easier to read and more informative on the web...
Hi @pcshingles,
Great to hear the problem got resolved!
Could you accept your reply above as solution to close this thread?
Regards
Covering the world! 9:00-10:30 AM Sydney, 4:00-5:30 PM CET (Paris/Berlin), 7:00-8:30 PM Mexico City
Check out the April 2024 Power BI update to learn about new features.