在 mutate 中使用 maptools::sunriset()
use maptools::sunriset() inside mutate
我正在尝试使用 dplyr
计算一组 lon/lat/timestamp 坐标的日出时间,使用 maptools 中的 sunriset
函数。这是一个可重现的例子。
library(maptools)
library(dplyr)
pts <- tbl_df(data.frame(
lon=c(12.08752,12.08748,12.08754,12.08760,12.08746,12.08748),
lat=c(52.11760,52.11760,52.11747,52.11755,52.11778,52.11753),
timestamp=as.POSIXct(
c("2011-08-12 02:00:56 UTC","2011-08-12 02:20:22 UTC",
"2011-08-12 02:40:15 UTC","2011-08-12 03:00:29 UTC",
"2011-08-12 03:20:26 UTC","2011-08-12 03:40:30 UTC"))
))
pts %>% mutate(sunrise=sunriset(as.matrix(lon,lat),
timestamp,POSIXct.out=T,
direction='sunrise')$time)
当我 运行 这段代码时,我收到错误
"Error: invalid subscript type 'closure'"
我猜这意味着我没有正确地将变量传递给 sunriset
。
这个方法确实有效,如果我没有dplyr
pts$sunrise<-sunriset(as.matrix(select(pts,lon,lat)),
pts$timestamp, POSIXct.out=T,
direction='sunrise')$time
但是,我有很多行(大约 6500 万行),即使只有一小部分,上述方法也非常慢。我希望 dplyr 会更快。如果有人对哪种方法可能最快有其他建议,我很乐意听取他们的意见。
sunr <- function(lon, lat, ts, dir='sunrise') {
# can also do matrix(c(pts$lon, pts$lat), ncol=2, byrow=TRUE) vs
# as.matrix(data.frame…
sunriset(as.matrix(data.frame(lon, lat)), ts, POSIXct.out=TRUE, direction=dir)$time
}
pts %>% mutate(sunrise = sunr(lon, lat, timestamp))
是一种处理方法(并且具有清洁 mutate
管道的副作用)但我不确定您为什么认为它会更快。无论哪种方式,瓶颈(很可能)是为调用 sunriset
创建矩阵,这将以任何一种方式发生。
maptools
源代码很容易理解,并且有一个非导出函数 maptools:::.sunrisetUTC()
可以:
".sunrisetUTC" <- function(jd, lon, lat, direction=c("sunrise", "sunset")) {
## Value: Numeric, UTC time of sunrise or sunset, in minutes from zero
## Z.
## --------------------------------------------------------------------
## Arguments: jd=julian day (real);
## lon=lat=longitude and latitude, respectively, of the observer in
## degrees;
## sunrise=logical indicating whether sunrise or sunset UTC should be
## returned.
您可以尝试将儒略日、经度、纬度和方向传递给它,而不是导出函数,以避免数据复制。但是,如果性能很关键,我会使用 Rcpp
编写基于 this.
的内联矢量化 C/C++ 函数
我正在尝试使用 dplyr
计算一组 lon/lat/timestamp 坐标的日出时间,使用 maptools 中的 sunriset
函数。这是一个可重现的例子。
library(maptools)
library(dplyr)
pts <- tbl_df(data.frame(
lon=c(12.08752,12.08748,12.08754,12.08760,12.08746,12.08748),
lat=c(52.11760,52.11760,52.11747,52.11755,52.11778,52.11753),
timestamp=as.POSIXct(
c("2011-08-12 02:00:56 UTC","2011-08-12 02:20:22 UTC",
"2011-08-12 02:40:15 UTC","2011-08-12 03:00:29 UTC",
"2011-08-12 03:20:26 UTC","2011-08-12 03:40:30 UTC"))
))
pts %>% mutate(sunrise=sunriset(as.matrix(lon,lat),
timestamp,POSIXct.out=T,
direction='sunrise')$time)
当我 运行 这段代码时,我收到错误
"Error: invalid subscript type 'closure'"
我猜这意味着我没有正确地将变量传递给 sunriset
。
这个方法确实有效,如果我没有dplyr
pts$sunrise<-sunriset(as.matrix(select(pts,lon,lat)),
pts$timestamp, POSIXct.out=T,
direction='sunrise')$time
但是,我有很多行(大约 6500 万行),即使只有一小部分,上述方法也非常慢。我希望 dplyr 会更快。如果有人对哪种方法可能最快有其他建议,我很乐意听取他们的意见。
sunr <- function(lon, lat, ts, dir='sunrise') {
# can also do matrix(c(pts$lon, pts$lat), ncol=2, byrow=TRUE) vs
# as.matrix(data.frame…
sunriset(as.matrix(data.frame(lon, lat)), ts, POSIXct.out=TRUE, direction=dir)$time
}
pts %>% mutate(sunrise = sunr(lon, lat, timestamp))
是一种处理方法(并且具有清洁 mutate
管道的副作用)但我不确定您为什么认为它会更快。无论哪种方式,瓶颈(很可能)是为调用 sunriset
创建矩阵,这将以任何一种方式发生。
maptools
源代码很容易理解,并且有一个非导出函数 maptools:::.sunrisetUTC()
可以:
".sunrisetUTC" <- function(jd, lon, lat, direction=c("sunrise", "sunset")) {
## Value: Numeric, UTC time of sunrise or sunset, in minutes from zero
## Z.
## --------------------------------------------------------------------
## Arguments: jd=julian day (real);
## lon=lat=longitude and latitude, respectively, of the observer in
## degrees;
## sunrise=logical indicating whether sunrise or sunset UTC should be
## returned.
您可以尝试将儒略日、经度、纬度和方向传递给它,而不是导出函数,以避免数据复制。但是,如果性能很关键,我会使用 Rcpp
编写基于 this.