我有一个相当大的数据框(1.65 MM行),看起来像这样:
date dayofyear time humidity temp
1 2008-01-01 1 300 99 38.2
2 2008-01-01 1 302 99 38.5
3 2008-01-01 1 304 99 38.5
4 2008-01-01 1 306 99 38.6
5 2008-01-01 1 308 99 38.9
6 2008-01-01 1 310 99 39.1
....
我想计算每一行的太阳正午,并将其作为新列添加到数据框中。 suncalc::getSunlightTimes(date)
函数使我可以在任何给定日期输入太阳正午。
如果我这样做:
solarNoons <- suncalc::getSunlightTimes(date = as.Date(dataFrame$date))
然后(显然)即使一个小时后,命令也不会完成。
一项观察-即使数据框中有1.65毫米的行,但只有约3000个唯一的日期。解决此问题的最佳方法是什么?只能调用一次getSunlightTimes()
3000次,并且仍然用新列中的值填充数据帧的1.65 MM行中的每一行吗?
这是我的第一次发贴,但是长时间的阅读和学习。非常感谢。
答案 0 :(得分:0)
仅在df$date
的每个不同值上调用一次昂贵的函数。现在,您将只调用3000次而不是165m次。应该快550倍。还要应用@RonakShah建议的任何特定于功能的加速技巧。
# Assign df$date <- as.Date(df$date) as early as possible, ideally right after you read it in
df$date <- as.Date(df$date)
library(dplyr)
df <- df %>% group_by(date) %>%
mutate(solarNoon = suncalc::getSunlightTimes(df$date, ...))
两种确保每个日期只打一次suncalc::getSunlightTimes()
的方法:
group_by(date) %>% ...
插入您的suncalc::getSunlightTimes(df$date, ...)
通话我赞成方法1,因为它很容易编码,并且通常会教给您很好的分解方法。始终尝试构建代码,以避免不必要地调用昂贵的函数一百万次。
答案 1 :(得分:0)
以下应该起作用。假设我们生成了一个200万行的数据框:
> N <- 2e6
> R <- data.frame(year = sample(2000:2009,N,TRUE),
+ dayofyear = sample(365,N,TRUE),
+ time = floor(runif(N,0,12))*100+floor(runif(N,0,60)),
+ humidity = 99,
+ temp = floor(runif(N,15,40)))
> R$date <- as.Date(with(R,strptime(paste(year,dayofyear),
+ "%Y %j", tz="GMT")))
> nrow(R)
[1] 2000000
> head(R)
year dayofyear time humidity temp date
1 2000 206 307 99 39 2000-07-24
2 2009 101 1019 99 16 2009-04-11
3 2004 307 547 99 21 2004-11-02
4 2003 270 1158 99 33 2003-09-27
5 2006 21 330 99 22 2006-01-21
6 2005 154 516 99 21 2005-06-03
>
在这种情况下,date
已经是Date
列,但是如果您是字符列,则:
> R$date <- as.Date(R$date)
应该只需要几秒钟。
现在,获取所有唯一日期值的列表。这应该很快:
> dates <- unique(R$date)
> print(length(dates))
[1] 3650
>
现在,在此向量上运行getSunlightTimes
。使用suncalc
版本0.4和R版本3.4.4在我的机器上只花了几秒钟:
> times <- suncalc::getSunlightTimes(dates, lat=0, lon=0)
现在,生成一个索引向量,以给出唯一日期R$date
的向量内dates
中每个日期的索引:
> i <- match(R$date, dates)
现在,通过相同的索引选择times
数据帧的行:
> solarNoons <- times[i,]
> nrow(solarNoons)
[1] 2000000
>
如果我们选择一行R:
> R[1234567,]
year dayofyear time humidity temp date
1234567 2002 24 535 99 17 2002-01-24
您会看到solarNoons
的相应行是该日期的结果:
> solarNoons[1234567,]
date lat lon solarNoon nadir
2616.352 2002-01-24 12:00:00 0 0 2002-01-24 12:13:14 2002-01-24 00:13:14
sunrise sunset sunriseEnd
2616.352 2002-01-24 06:09:42 2002-01-24 18:16:46 2002-01-24 06:11:58
sunsetStart dawn dusk
2616.352 2002-01-24 18:14:30 2002-01-24 05:47:49 2002-01-24 18:38:39
nauticalDawn nauticalDusk nightEnd
2616.352 2002-01-24 05:22:22 2002-01-24 19:04:06 2002-01-24 04:56:50
night goldenHourEnd goldenHour
2616.352 2002-01-24 19:29:38 2002-01-24 06:38:39 2002-01-24 17:47:49
>
如果需要,可以将两个数据框合并在一起:
> R2 <- cbind(R, solarNoons)
所有这些都假设“ 1.65 MM”表示165万。如果您的意思是165亿(即一万亿美元),那么您将需要一台更大的计算机。