r - 将一天中的阶段分配给每个日期 - 但速度很快
问题描述
我想将列表中的元素与数据框中的间隔进行比较,并将相应的间隔分配给该元素。
就我而言,我想获得一天中的一个阶段(即早上、白天、晚上、晚上)进行测量。我找到了 R 包“suncalc”,它为这些阶段创建了间隔,并且还有一个解决方案来分配一天中的这些阶段。但是这很慢,我想知道如何更快地做到这一点。
#make a list of different days and times
times<-seq.POSIXt(from=Sys.time(),
to=Sys.time()+2*24*60*60,length.out = 50)
#load the suncalc package
library(suncalc)
#a function to get a phase for one point in time
get.dayphase<-function(x){
phases<-getSunlightTimes(date=as.Date(x,tz=Sys.timezone()),
lat=52.52,lon=13.40,
tz=Sys.timezone())
if(x<phases$nightEnd)return("night_morning")
if(x>=phases$nightEnd&x<phases$goldenHourEnd)return("morning")
if(x>=phases$goldenHourEnd&x<phases$goldenHour)return("day")
if(x>=phases$goldenHour&x<phases$night)return("evening")
if(x>=phases$night)return("night_evening")
}
#use sapply to get a phase for each point in time of the list
df=data.frame(time=times,dayphase=sapply(times,get.dayphase))
理想但缓慢的结果:
head(df)
time dayphase
1 2019-09-05 16:12:08 day
2 2019-09-05 17:10:55 day
3 2019-09-05 18:09:41 day
4 2019-09-05 19:08:28 evening
5 2019-09-05 20:07:14 evening
6 2019-09-05 21:06:01 evening
基本上,这就是我想要的。但是当我在很多时间点上运行它时它太慢了。getSunlightTimes()
也可以获取日期列表并返回数据表,但我不知道如何处理以获得所需的结果。谢谢你的帮助
解决方案
使您的流程变慢的很可能是sapply
函数,它基本上是一个隐藏for
循环。
为了提高性能,您需要对代码进行矢量化。可以采用getSunlightTimes
日期向量。此外,dplyr 包中的函数不是使用一系列if
语句,而是case_when
简化了代码,并且应该减少逻辑操作的数量。
library(dplyr)
times<-seq.POSIXt(from=Sys.time(),
to=Sys.time()+2*24*60*60,length.out = 50)
library(suncalc)
#a function to get phases for all of the times
phases<-getSunlightTimes(as.Date(times),
lat=52.52,lon=13.40,
tz=Sys.timezone(),
keep = c("nightEnd", "goldenHourEnd", "goldenHour", "night"))
dayphase<-case_when(
times < phases$nightEnd ~ "night_morning",
times < phases$goldenHourEnd ~ "morning",
times < phases$goldenHour ~ "day",
times < phases$night ~ "evening",
TRUE ~ "night_evening"
)
这应该提供显着的改进。如果您每天有大量时间,则可以进一步提高性能。如果是这种情况,请每天计算一次阶段数据帧,然后将此结果用作各个时间的查找表。
推荐阅读
- java - 如何使用android api将本地文件从外部目录上传到谷歌驱动器?
- c++ - c++中的第一个重复字符
- python - Kivy 应用程序运行后立即出现 Python 错误
- c - C 语言以二进制形式访问内存
- flutter - Flutter - CupertinoActionSheet / CupertinoActionSheetAction 背景颜色在设备上与模拟器中不同
- javascript - 为什么 Tabulator 没有从我的 JSON 数据生成表格?
- c++ - 二叉搜索树 - C++ 中的唯一值
- github - 如何删除 Github 环境
- c - 计算数字的总和。如果数字重复,不要计算它
- reporting-services - 根据报表服务器中另一个数据集的值过滤 Tablix 上的数据