簡體   English   中英

使用匯總(dplyr)的結果來改變原始數據幀

[英]Using the result of summarise (dplyr) to mutate the original dataframe

我有一個相當大的數據框,其中包含一列POSIXct日期時間(每小時數據約為10年)。 我會在夏令時期間標記當天所有的行。 例如,如果夏令時開始於'2000-04-02 03:00:00'(DOY = 93),我希望可以標記前兩個小時的DOY = 93。 雖然我是dplyr的新手,但我會盡可能地使用這個包,盡可能避免for循環

例如:

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

現在,我將在跨度數據幀中“管道”上述結果,而不使用低效的for循環

解決方案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)來填充Daylight-savings日的正確值

limits$CHECK = FALSE
limits$CHECK[(limits$DOY >= limits$minDOY) & (limits$DOY <= limits$maxDOY) ] = TRUE

正如@beetroot在評論中指出的那樣,您可以通過加入來完成此任務:

limits = span %>% 
   group_by(YEAR) %>% 
   summarise(minDOY=min(DOY[DLS]),maxDOY=max(DOY[DLS])) %>%
   inner_join(span, by='YEAR')
#    YEAR minDOY maxDOY                date DOY   DLS
# 1  2000     93    303 2000-01-01 00:00:00   1 FALSE
# 2  2000     93    303 2000-01-01 01:00:00   1 FALSE
# 3  2000     93    303 2000-01-01 02:00:00   1 FALSE
# 4  2000     93    303 2000-01-01 03:00:00   1 FALSE
# 5  2000     93    303 2000-01-01 04:00:00   1 FALSE
# 6  2000     93    303 2000-01-01 05:00:00   1 FALSE
# 7  2000     93    303 2000-01-01 06:00:00   1 FALSE
# 8  2000     93    303 2000-01-01 07:00:00   1 FALSE
# 9  2000     93    303 2000-01-01 08:00:00   1 FALSE
# 10 2000     93    303 2000-01-01 09:00:00   1 FALSE

dplyr是一個很棒的工具,但在這種情況下,我不確定這是最好的工作。 這完成了你的任務:

span$CHECK <- ave(dst(span$date), as.Date(span$date, tz = tz(span$date)), FUN = any)

我認為ave對於這個函數來說是一個糟糕的名字,但如果你能記住它存在,當你想要將摘要加入到它來自的data.frame時,它通常非常有用。

按照@aosmith的建議,完成工作的最佳解決方案是。

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

使用ave功能是一個不錯的選擇,但我個人更喜歡堅持'dplyr'包。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM