【问题标题】:use maptools::sunriset() inside mutate在 mutate 中使用 maptools::sunriset()
【发布时间】:2015-09-28 00:19:10
【问题描述】:

我正在尝试使用 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)

当我运行这段代码时,我得到了错误

“错误:无效的下标类型‘闭包’”

我猜这意味着我没有正确地将变量传递给sunriset

如果我不使用dplyr,此方法确实有效

pts$sunrise<-sunriset(as.matrix(select(pts,lon,lat)), 
                    pts$timestamp, POSIXct.out=T, 
                    direction='sunrise')$time

但是,我有很多行(大约 6500 万行),即使只有一小部分,上述方法也非常慢。我希望 dplyr 会更快。如果有人对最快的方法有其他建议,我很想听听。

【问题讨论】:

  • 您可以使用 data.table 尝试以下操作。 setDT(pts)[,sunrise := sunriset(matrix(c(lon, lat), ncol = 2, nrow = 6, byrow = FALSE), timestamp, POSIXct.out=T, direction='sunrise')[2]][]
  • 矩阵副本(+ sunriset 不是 C/C++ 支持的事实)可能是 @jazzurro 花费时间的事情(我扩展了我的答案)。
  • @hrbrmstr 我明白了。在这种情况下,使用 dplyr 或 data.table 不会加快这个过程。谢谢提供信息。 :)

标签: r dplyr maptools


【解决方案1】:
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++ 函数。

【讨论】:

  • hrbrmstr,感谢您提供的信息。到目前为止,我的使用是一次性的,我已经能够忍受性能问题。如果我需要始终如一地获得快速性能,我会尝试您的建议。万一其他人读到这个,我碰巧看到了这段代码:stjarnhimlen.se/comp/sunriset.c 它似乎是在 c 中的 sunriset 函数的实现
猜你喜欢
  • 1970-01-01
  • 2013-07-19
  • 1970-01-01
  • 2017-12-23
  • 2018-09-09
  • 2015-03-20
  • 2015-03-20
  • 1970-01-01
  • 2013-05-16
相关资源
最近更新 更多