【发布时间】:2014-10-05 15:33:21
【问题描述】:
我有一个相当大的数据框,其中有一列 POSIXct 日期时间(约 10 年的每小时数据)。我会标记当天属于夏令时的所有行。例如,如果夏令时从 '2000-04-02 03:00:00' (DOY=93) 开始,我希望可以标记 DOY=93 的前两个小时。 虽然我是 dplyr 的新手,但我会尽可能地使用这个包并尽可能地避免 for-loops
例如:
library(lubridate)
sd = ymd('2000-01-01',tz="America/Denver")
ed = ymd('2005-12-31',tz="America/Denver")
span = data.frame(date=seq(from=sd,to=ed, by="hour"))
span$YEAR = year(span$date)
span$DOY = yday(span$date)
span$DLS = dst(span$date)
要查找应用夏令时的一年中的不同日子,我使用 dplyr
library(dplyr)
limits = span %.% group_by(YEAR) %.% summarise(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS]))
这给了
YEAR minDOY maxDOY
1 2000 93 303
2 2001 91 301
3 2002 97 300
4 2003 96 299
5 2004 95 305
6 2005 93 303
现在我将在 span 数据帧中“管道”上述结果,而不使用效率低下的 for-loop。
解决方案 1
在@aosmith 的帮助下,只需两个命令即可解决问题(并避免使用“解决方案 2”中的 inner_join):
limits = span %>% group_by(YEAR) %>% mutate(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS]),CHECK=FALSE)
limits$CHECK[(limits2$DOY >= limits$minDOY) & (limits$DOY <= limits$maxDOY) ] = TRUE
解决方案 2
在@beetroot 和@matthew-plourde 的帮助下,问题已经解决了: 缺少一个内部连接:
limits = span %>% group_by(YEAR) %>% summarise(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS])) %>% inner_join(span, by='YEAR')
然后我添加了一个新列 (CHECK) 来填充夏令时的正确值
limits$CHECK = FALSE
limits$CHECK[(limits$DOY >= limits$minDOY) & (limits$DOY <= limits$maxDOY) ] = TRUE
【问题讨论】:
-
所以你想在 span 中有两个新列,minDOY 和 maxDOY 并且它们的值在每一行和各自的年份重复?这可能可以用 left_join 完成,但如果没有示例数据就无法测试。
-
感谢@beetroot 的提示。我现在就试试!对于示例数据...上面的代码对您不起作用?
-
啊,我只是没有安装 lubridate,现在我懒得这样做了;)
-
没问题,甜菜根!在您的帮助和 matthew-plourde 的帮助下,一切都已解决。多亏了 oropendola,现在我有了一个新工具。见上面的代码。
-
向现有数据集添加新列似乎是
mutate的工作,而不是summarise加入的工作。