我有一个名为result
的 Dataframe ,看起来像这样。
| 后来|液化天然气|夜|
| --------------|--------------|--------------|
| 41.60701|1.000831|2019-06-19 2019-06-19|
| 41.98151|一九七三零五九|2020-04-11 2020-04-11 2020-04-11|
| ……|……|……|
基本上,我会添加4列。一列是日落的时间,第二列是日出的时间,第三列是以小时为单位的夜间持续时间,最后第四列是采样工作(我只是将时间buff添加到夜间持续时间)。我通过使用以下代码中的一个循环来做到这一点(unsing suncalc包用于getSunlightTimes
)。
library("plyr")
library("dplyr")
library("reshape")
library("data.table")
library("stringr")
library("tidyr")
library("ineq")
library("suncalc")
library(suncalc)
time_buff <- 0.30
posta <- ls()
sorti <- ls()
night_hours <- ls()
temp <- result
for (i in 1:dim(temp)[1]) {
lat <- temp$lat[i]
long <- temp$lng[i]
sset <- as.Date(temp$Night[i])
sris <- sset + 1
Tsset <- getSunlightTimes(sset, lat, long,
keep = c("sunrise", "sunset"), tz = "UTC"
)$sunset
Tsris <- getSunlightTimes(sris, lat, long,
keep = c("sunrise", "sunset"), tz = "UTC"
)$sunrise
posta[i] <- Tsset
sorti[i] <- Tsris
night_hours[i] <- round(as.numeric(Tsris - Tsset), 2)
}
# fetch results
temp$sun_set <- as.POSIXct(as.numeric(unlist(posta)),
origin = "1970-01-01", tz = "UTC"
)
temp$sun_rise <- as.POSIXct(as.numeric(unlist(sorti)),
origin = "1970-01-01", tz = "UTC"
)
temp$night_hours <- as.numeric(unlist(night_hours))
temp$night_effort <- as.numeric(temp$night_hours) + (time_buff * 2)
result <- temp
但是它需要很长的时间来运行。所以,我想知道是否有其他最简单的方法来做到这一点,例如使用dplyr包中的mutate函数而不是使用循环?
2条答案
按热度按时间dwbf0jvd1#
基本的计算可以用
rowwise
在tidyverse中完成-即getSunlightTimes
对于lat
,long
没有矢量化,所以我们一次只能提供一个值。如果'lat','long',而不是rowwise
有重复,最好先做group_by(lat, lng)
,然后使用first(lat)
,getSunlightTimes
调用中的first(lng)
数据
m3eecexj2#
更新:
我们不需要使用
group_by
或rowwise
。如果我们有多个坐标,阅读?getSunlightTimes
告诉我们使用data
作为替代:date:日期。单个或多个日期。YYYY-MM-DD
纬度:数值。单纬度
lon:数字。单经度
data:data. frame。使用date、lat、lon传递多个坐标的替代方法
keep:字符。要保留的变量的向量。查看详细信息
tz:〉character.结果的时区
所以我们可以将数据框作为一个整体传递给函数,但是需要为列指定正确的名称。
我们可以使用
rowwise
代替循环,或者更好的方法是group_by(lat, long)
,并且只为每个组传递第一个lat和long。