我正在使用geosphere软件包中的daylength函数来计算两点之间某个位置的日长。根据具体的个人和位置,我平均每天的天数会有所不同。
当我对变量进行硬编码(即为lat和date提供特定值)时函数可以工作时,但是当我提供值的向量并得到以下错误和警告消息时,该函数就不起作用:
Error in mutate_impl(.data, dots) : Evaluation error: NA/NaN argument.
In addition: Warning messages:
1: In doy.prev:doy :
numerical expression has 379 elements: only the first used
2: In doy.prev:doy :
numerical expression has 379 elements: only the first used
我知道此错误与我的日长计算有关,因为省略该代码的另一部分可以正常运行。
我的代码和数据的子集(即前25个观察值):
df %>%
mutate(mean.lat = if_else((ID == lag(ID) & site != lag(site)),
(lat + lag(lat))/2, NA_real_),
doy.prev = if_else((ID == lag(ID) &
site != lag(site)),
lag(yday(ts)),
NA_real_),
mean.day = if_else((ID == lag(ID) &
site != lag(site) &
yday(ts) != yday(lag(ts)) &
!is.na(mean.lat) &
!is.na(doy.prev)),
mean(daylength(mean.lat, doy.prev:doy)),
timeS))
dput(df)
structure(list(ID = structure(c(1L, 2L, 2L, 3L, 3L, 3L, 3L, 3L,
3L, 3L, 3L, 3L, 3L, 3L, 4L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 7L, 8L,
8L), .Label = c("NB2014.12", "NB2014.13", "NB2014.14", "NB2014.15",
"NB2014.16", "NB2014.42", "NB2014.43", "NB2014.44", "NB2014.45",
"NB2014.47", "NB2014.48", "NB2014.49", "NB2014.70", "NB2014.71",
"NB2014.72", "NB2014.73", "NB2014.74", "NB2014.75", "NB2014.76",
"NB2014.77", "NB2014.78", "NB2014.79", "NB2014.80", "NB2014.81",
"NB2015.156", "NB2015.157", "NB2015.158", "NB2015.159", "NB2015.160",
"NB2015.312", "NB2015.313", "NB2015.314", "NB2015.315", "NB2015.316",
"NB2015.317", "NB2015.318", "NB2015.320", "NB2015.321", "NB2015.322",
"NB2015.323", "NB2015.324", "NB2015.325", "NB2015.326", "NB2015.327",
"NB2015.328", "NB2015.329", "NB2015.330", "NB2015.331", "NB2015.332",
"NB2015.333", "NB2015.334", "NB2015.335", "NB2015.336", "NB2015.337",
"NB2015.338", "NB2015.339", "NB2015.340", "NB2015.341", "NB2015.342",
"NB2015.343", "NB2015.344", "NB2015.345", "NB2015.346", "NB2015.347",
"NB2015.348", "NB2015.349", "NB2015.350", "NB2015.351", "NB2018.10",
"NB2018.11", "NB2018.12", "NB2018.13", "NB2018.14", "NB2018.15",
"NB2018.16", "NB2018.17", "NB2018.18", "NB2018.19", "NB2018.20",
"NB2018.21", "NB2018.22", "NB2018.23", "NB2018.24", "NB2018.25",
"NB2018.26", "NB2018.27", "NB2018.28", "NB2018.29", "NB2018.30",
"NB2018.31", "NB2018.32", "NB2018.33", "NB2018.34", "NB2018.35",
"NB2018.37", "NB2018.38", "NB2018.39", "NB2018.40", "NB2018.41",
"NB2018.42", "NB2018.43", "NB2018.44", "NB2018.45", "NB2018.46",
"NB2018.47", "NB2018.48", "NB2018.49", "NB2018.5", "NB2018.50",
"NB2018.51", "NB2018.52", "NB2018.53", "NB2018.54", "NB2018.55",
"NB2018.56", "NB2018.57", "NB2018.58", "NB2018.59", "NB2018.6",
"NB2018.60", "NB2018.61", "NB2018.62", "NB2018.63", "NB2018.64",
"NB2018.7", "NB2018.8", "NB2018.9"), class = "factor"), site = c("Tantramar",
"Tantramar", "HPWLR", "Tantramar", "Beaubassin", "Marsh Landings",
"Eddie rd. ", "Marsh Landings", "Marsh Landings", "Marsh Landings",
"Eddie rd. ", "Beaubassin", "AMHRST", "HPWLR", "Tantramar", "Tantramar",
"Fork Field Farms", "WNERR", "GB_ferryway", "GB_thomas", "Tantramar",
"HPWLR", "Tantramar", "Tantramar", "Marsh Landings"), lat = c(45.900303030303,
45.900303030303, 45.83, 45.900303030303, 45.85, 45.85, 45.85,
45.85, 45.85, 45.85, 45.85, 45.85, 45.79, 45.83, 45.900303030303,
45.900303030303, 45.94, 43.34, 43.09, 43.08, 45.900303030303,
45.83, 45.900303030303, 45.900303030303, 45.85), doy = c(213,
206, 206, 217, 217, 217, 217, 217, 218, 218, 218, 218, 218, 218,
194, 206, 207, 211, 211, 211, 220, 220, 207, 210, 210), ts = structure(c(1406899801.4133,
1406297348.1112, 1406299522.4141, 1407276094.4158, 1407277417.7616,
1407279028.1764, 1407279972.1813, 1407281880.08955, 1407285413.4387,
1407314856.6032, 1407315906.52065, 1407316678.29125, 1407316887.28,
1407319828.1424, 1405278154.7126, 1406330632.0613, 1406364501.8284,
1406713079.0338, 1406716251.3933, 1406716449.5783, 1407490305.4993,
1407491817.085, 1406370738.3239, 1406655731.0996, 1406673688.1819
), class = c("POSIXct", "POSIXt"), tzone = "UTC"), timeS = c(NA,
NA, 2174.30289983749, NA, 1323.34579992294, 1610.41479992867,
944.004900217056, 1907.90824985504, NA, NA, 1049.91744995117,
771.77060008049, 208.988749980927, 2940.86240005493, NA, NA,
33869.7670998573, 348577.20539999, 3172.35950016975, 198.18499994278,
NA, 1511.5857000351, NA, NA, 17957.0822999477)), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -25L))
答案 0 :(得分:1)
在普通R中:
d <- data.frame(
meanLat = c(45.0, 44.6),
doy = c(207,211),
doy.prev = 206:207
)
library(geosphere)
# one row
sum(daylength(d$meanLat[1], d$doy.prev[1]:d$doy[1]))
#[1] 29.96547
# all rows
apply(d, 1, function(x) sum(daylength(x[1], x[3]:x[2])))
#[1] 29.96547 74.25768
# you could also first make a proper long matrix
x <- do.call(rbind, apply(d, 1, function(x) cbind(x[1], x[3]:x[2])))
# followed by
tapply(daylength(x[,1], x[,2]), x[,1], sum)
# 44.6 45
#74.25768 29.96547
答案 1 :(得分:0)
我添加了其他过滤器,并给出了以下警告。有什么提示吗?
df %>%
mutate(mean.lat = if_else((ID == lag(ID) & site != lag(site)),
(lat + lag(lat))/2, NA_real_),
doy.prev = if_else((ID == lag(ID) &
site != lag(site)),
lag(yday(ts)),
NA_real_)) %>%
filter(!is.na(doy.prev)) %>%
mutate(mean.day = if_else(((ID == lag(ID) &
site != lag(site) &
yday(ts) != yday(lag(ts))) &
!is.na(mean.lat) &
!is.na(doy.prev)),
mean(daylength(mean.lat, doy.prev:doy)),
timeS))
12 NB2014.16 GB_ferryway 43.1 211 2014-07-30 10:30:51 3172. 43.2 211 3172.
13 NB2014.16 GB_thomas 43.1 211 2014-07-30 10:34:09 198. 43.1 211 198.
14 NB2014.42 HPWLR 45.8 220 2014-08-08 09:56:57 1512. 45.9 220 1512.
15 NB2014.44 Marsh Landings 45.8 210 2014-07-29 22:41:28 17957. 45.9 210 17957.
Warning messages:
1: In doy.prev:doy :
numerical expression has 15 elements: only the first used
2: In doy.prev:doy :
numerical expression has 15 elements: only the first used
答案 2 :(得分:0)
我无法找到一种方法来使Daylength函数在dplyr中工作。但是,这是一种解决方法:
df2 <- df %>%
filter(!is.na(meanLat))
df2$timeHday = apply((df2 %>% select(meanLat, doy.local, doy.prev1)),
1,
function(x) sum(daylength(x[1], x[3]:x[2])))
df <- df %>% left_join(df2, by = c("ID", "ts.mn"))
非常感谢Robert Hijmans的帮助!