简体   繁体   English

尝试将功能应用于R中的数据帧行时出错

[英]Errors attempting to applying function to data frame rows in R

I wrote a very simple function (which works well) that returns the timezone given a set of coordinates: 我编写了一个非常简单的函数(效果很好),该函数在给定一组坐标的情况下返回时区:

library(XML)
findTZ <- function(lon, lat, date=Sys.Date())
{ apiurl <- sprintf("https://maps.googleapis.com/maps/api/timezone/%s?location=%s,%s&timestamp=%d&sensor=%s", 
                    "xml", lat, lon, as.numeric(as.POSIXct(date)), "false")
  TZ <- xmlParse(readLines(apiurl))[["string(//time_zone_id)"]]
  return(TZ)
}

findTZ(-112.86, 53.61) # example

However, when I try to run the function on a list of coordinates in a dataframe I get an error: Error in file(con, "r") : invalid 'description' argument 但是,当我尝试在数据框中的坐标列表上运行该函数时,出现错误: Error in file(con, "r") : invalid 'description' argument

Any hints at what I'm getting wrong here? 有什么暗示我在这里错了吗? It seems like it should be very simple. 看起来应该很简单。

Here's the very basic data I'm testing on: 这是我正在测试的非常基本的数据:

DF <- data.frame(
  longitude = c(-122, -112, -102),
  latitude = c(54, 53, 52)
)

DF$timezone = findTZ(lon=DF$longitude, lat=DF$latitude)

Thank you for any pointers! 谢谢您的指点!

EDIT / ADDITION 编辑/添加

After implementing the answer from @Floo0 I tried implementing the same solution with another function for calculating sunrise/set times using the same location data (and that I want to return in local time, hence the timezone function). 在实现@ Floo0的答案之后,我尝试使用另一个函数来实现相同的解决方案,该函数使用相同的位置数据来计算日出/设置时间(并且我想在本地时间返回,因此是时区函数)。

Here's the sunrise function: 这是日出功能:

    library(maptools)
SSun <- function(lon, lat, date, deg=0, dir, tzone)
{ # deg = solar depth: rise/set=0, civil=6, nautical=12, astronomical=18
  # dir = direction: sunrise="dawn", sunset="dusk"
  # tzone  = time zone of output, NOT of location
  siteX <- SpatialPoints(matrix(c(lon, lat), nrow=1), proj4string=CRS("+proj=longlat +datum=WGS84"))
  dateX <- as.POSIXct(date, tz=tzone)
  duskX <- crepuscule(siteX, dateX, solarDep=deg, direction=dir, POSIXct.out=TRUE)
  duskX <- duskX$time # keep only date and time, discard day_frac
  return(duskX)
}

SSun(-112.86, 53.61, "2016-09-25", deg=0, dir="dawn", tzone="America/Edmonton") # example

And the updated timezone function: 并更新了时区功能:

library(tidyverse); library(xml2)
findTZ <- function(lon, lat, date=Sys.Date()){ 
  apiurl <- sprintf("https://maps.googleapis.com/maps/api/timezone/%s?location=%s,%s&timestamp=%d&sensor=%s", 
                    "xml", lat, lon, as.numeric(as.POSIXct(date)), "false")
  read_xml(apiurl) %>% xml_find_first(".//time_zone_id") %>% xml_text
}

findTZ(-112.86, 53.61) # example

And the code I used to call both functions: 以及我用来调用这两个函数的代码:

DF %>% mutate(date = as.POSIXct(date),
              TZ = map2_chr(longitude, latitude, findTZ),
              sunrise = SSun(longitude, latitude, date, deg=0, dir="dawn", tzone=TZ))

I feel like I must be misunderstanding how this works. 我觉得我一定误会了它的工作原理。 Any insights? 有什么见解吗?

You can do the following (using xml2 instead of XML as i find it easier to use) 您可以执行以下操作(使用xml2代替XML因为我发现它更易于使用)

require(xml2)
findTZ <- function(lon, lat, date=Sys.Date()){ 
  apiurl <- sprintf("https://maps.googleapis.com/maps/api/timezone/%s?location=%s,%s&timestamp=%d&sensor=%s", 
                    "xml", lat, lon, as.numeric(as.POSIXct(date)), "false")
  read_xml(apiurl) %>% xml_find_first(".//time_zone_id") %>% xml_text
}

To loop through your test data you can use: 要遍历测试数据,可以使用:

require(tidyverse)
DF %>% mutate(TZ = map2_chr(longitude, latitude, findTZ))

Which gives you: 这给你:

  longitude latitude                TZ
1      -122       54 America/Vancouver
2      -112       53  America/Edmonton
3      -102       52    America/Regina

As @Rich Scriven points out correctly you need to loop through the data somewhere. 正如@Rich Scriven正确指出的那样,您需要遍历某个地方的数据。 This loop is "hidden" in the map2_chr call. map2_chr调用中,此循环是“隐藏的”。

考虑mapply将每对按元素值传递给函数以返回向量:

DF$timezones <- mapply(findTZ, DF$longitude, DF$latitude)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM