1

I have a data frame containing latitude and longitude coordinates. The function I have returns a one row data frame with data about those coordinates. I want to apply this function for all of the coordinates in the data frame and then bind these results.

My functions look like this:

getForecast <- function(lat, lon){
    currentTime = Sys.time();
    gmtTime = as.POSIXct(currentTime)
    gmtTime <- toString(as.POSIXct(gmtTime, "%Y-%m-%dT%H:%M"))
    arr <- unlist(strsplit(gmtTime, ' '))
    curTime <- paste(arr[1], 'T', arr[2], sep="")
    forecast <- get_forecast_for(lat, lon, curTime)
    return(forecast)
  }
getDailyForecast <- function(lat, lon){
    forecast <- getForecast(lat, lon)
    hourly_forecast <- forecast$current
    weather_data <- select(hourly_forecast, 'time', 'temperature', 'humidity', 'windSpeed', 'windBearing', 'cloudCover', 'visibility', 'pressure', 'ozone', 'summary' )
    return(weather_data)
  }

  curForecast <- getDailyForecast(41.870, -87.647)
  curForecast$Lat <- 41.870
  curForecast$Lon <- -87.647
  print(curForecast)

  n_locations <- reactive({
    select(nodeLocations(), Lat, Lon)
  })

get_forecast_for(lat, lon, curTime) in getForecast is from the darksky API

The getDailyForecast returns this:

time                    temperature humidity windSpeed windBearing cloudCover visibility pressure  ozone       summary     
2019-04-23 16:57:10       51.32     0.67      6.27         103       0.78       8.42      1017.38    331.68   Mostly Cloudy 

the curForecast looks like this after adding the latitude and longitude:

time temperature humidity windSpeed windBearing cloudCover visibility pressure  ozone       summary      Lon       Lat
1 2019-04-23 16:57:10       51.32     0.67      6.27         103       0.78       8.42  1017.38 331.68 Mostly Cloudy 41.87838 -87.62768

The n_locations looks like this:

Lat      Lon
-87.62768 41.87838
-87.71299 41.75124
-87.57535 41.72246

I want a datatable that looks like this:

time                temperature    humidity   windSpeed windBearing cloudCover visibility pressure  ozone       summary      Lon       Lat
2019-04-23 16:57:10       51.32     0.67      6.27         103       0.78       8.42      1017.38   331.68      Mostly Cloudy 41.87838 -87.62768
2019-04-23 16:58:14       55.13      0.6      5.93          91       0.76       9.73      1017.18   329.9       Mostly Cloudy 41.75124 -87.71299
2019-04-23 16:59:13       50.22     0.71      6.33          87       0.87       7.92      1017.4   329.59      Mostly Cloudy 41.72246 -87.57535

EDIT: for:

do.call(rbind, apply(coordinates, 2, function(z) getDailyForecast(z[1], z[2]))) 

I get this result:

time temperature humidity windSpeed windBearing cloudCover visibility pressure  ozone       summary
Lat 2019-04-23 00:33:18      -44.83     0.53     21.68         137       0.25       6.91  1024.57 241.12 Partly Cloudy
Lon 2019-04-23 08:33:18       53.69     0.79     10.19         239       0.44       3.90  1028.36 441.36 Partly Cloudy

It only did the first two rows of coordinates

It should look like this:

    Lat      Lon         time                temperature    humidity   windSpeed windBearing cloudCover visibility pressure  ozone       summary           
    41.87838 -87.62768    2019-04-23 16:57:10       51.32     0.67      6.27         103       0.78       8.42      1017.38   331.68      Mostly Cloudy 
    41.75124 -87.71299    2019-04-23 16:58:14       55.13      0.6      5.93          91       0.76       9.73      1017.18   329.9       Mostly Cloudy 
    41.72246 -87.57535    2019-04-23 16:59:13       50.22     0.71      6.33          87       0.87       7.92      1017.4   329.59      Mostly Cloudy 

1 Answers1

1

The classic way to solve this would be to use the apply function first and then bind the rows together with do.call:

do.call(rbind, apply(mydata, 1, function(z) getDailyForecast(z[1], z[2])))

However this might not be the most efficient way (in terms of computation speed). So if you have a very large dataset you might want to look for a different solution.

Cettt
  • 11,460
  • 7
  • 35
  • 58