【问题标题】:Merging aggregate data in R在 R 中合并聚合数据
【发布时间】:2011-07-24 20:04:21
【问题描述】:

在我的previous question 将每小时数据汇总为每日数据之后,我想继续 (a) 每月汇总和 (b) 将每月汇总合并到原始数据框中。

我的原始数据框如下所示:

Lines <- "Date,Outdoor,Indoor
01/01/2000 01:00,30,25
01/01/2000 02:00,31,26
01/01/2000 03:00,33,24
02/01/2000 01:00,29,25
02/01/2000 02:00,27,26
02/01/2000 03:00,39,24
12/01/2000 02:00,27,26
12/01/2000 03:00,39,24
12/31/2000 23:00,28,25"

每日汇总已在我的previous question 中得到答复,然后我可以从那里找到生成每月汇总的方法,如下所示:

Lines <- "Date,Month,OutdoorAVE
01/01/2000,Jan,31.33
02/01/2000,Feb,31.67
12/01/2000,Dec,31.33"

OutdoorAVE 是每日最低和最高室外温度的月平均值。我最终想要的是这样的:

Lines <- "Date,Outdoor,Indoor,Month,OutdoorAVE
01/01/2000 01:00,30,25,Jan,31.33
01/01/2000 02:00,31,26,Jan,31.33
01/01/2000 03:00,33,24,Jan,31.33
02/01/2000 01:00,29,25,Feb,31.67
02/01/2000 02:00,27,26,Feb,31.67
02/01/2000 03:00,39,24,Feb,31.67
12/01/2000 02:00,27,26,Dec,31.33
12/01/2000 03:00,39,24,Dec,31.33
12/31/2000 23:00,28,25,Dec,31.33"

我不知道如何做到这一点。非常感谢任何帮助。

【问题讨论】:

    标签: datetime r merge aggregate


    【解决方案1】:

    尝试ave 和例如POSIXlt 提取月份:

    zz <- textConnection(Lines)
    Data <- read.table(zz,header=T,sep=",",stringsAsFactors=F)
    close(zz)
    
    Data$Month <- strftime(
         as.POSIXlt(Data$Date,format="%m/%d/%Y %H:%M"),
         format='%b')
    Data$outdoor_ave <- ave(Data$Outdoor,Data$Month,FUN=mean)
    

    给:

    > Data
                  Date Outdoor Indoor Month outdoor_ave
    1 01/01/2000 01:00      30     25   Jan    31.33333
    2 01/01/2000 02:00      31     26   Jan    31.33333
    3 01/01/2000 03:00      33     24   Jan    31.33333
    4 02/01/2000 01:00      29     25   Feb    31.66667
    5 02/01/2000 02:00      27     26   Feb    31.66667
    6 02/01/2000 03:00      39     24   Feb    31.66667
    7 12/01/2000 02:00      27     26   Dec    31.33333
    8 12/01/2000 03:00      39     24   Dec    31.33333
    9 12/31/2000 23:00      28     25   Dec    31.33333
    

    编辑:然后如上所示在数据中计算月份并使用合并:

    zz <- textConnection(Lines2) # Lines2 is the aggregated data
    Data2 <- read.table(zz,header=T,sep=",",stringsAsFactors=F)
    close(zz)
    
    > merge(Data,Data2[-1],all=T)
      Month             Date Outdoor Indoor OutdoorAVE
    1   Dec 12/01/2000 02:00      27     26      31.33
    2   Dec 12/01/2000 03:00      39     24      31.33
    3   Dec 12/31/2000 23:00      28     25      31.33
    4   Feb 02/01/2000 01:00      29     25      31.67
    5   Feb 02/01/2000 02:00      27     26      31.67
    6   Feb 02/01/2000 03:00      39     24      31.67
    7   Jan 01/01/2000 01:00      30     25      31.33
    8   Jan 01/01/2000 02:00      31     26      31.33
    9   Jan 01/01/2000 03:00      33     24      31.33
    

    【讨论】:

    • @Joris Meys:我的问题是,outdoorAVE 位于另一个只有月份和平均列的数据帧(比如 Data.Month)上,并且一年只有 12 行。 OutdoorAVE 不是按照您上面写的那样计算的,而是根据年度每小时数据的汇总(每天然后每月)计算的。所以我想要的是在原始数据框中添加一列(即上面示例中的数据),其中该列取自另一个数据集(例如 Data.Monthly)。
    • @ery:在您的评论中,您说Data.Monthly 只有 2 列(月和平均值),但在您的原始问题中有 3 列。
    • @Joshua:哎呀,应该是 3,虽然我只对将户外列粘贴回原始数据框感兴趣。
    • @Joris:是的,这行得通,谢谢。我的下一个问题显然是我一小时的时间戳不是 00-23,而是 01-24。所以我每 24 行就有一个 NA 条目。有什么好的解决方案吗?
    • @ery :在计算月份之前运行Data$Date &lt;- gsub("24:00","00:00",Data$Date)。
    【解决方案2】:

    这是一个 zoo/xts 解决方案。请注意,Month 在这里是数字,因为您不能在 zoo/xts 对象中混合类型。

    require(xts) # loads zoo too
    Lines1 <- "Date,Outdoor,Indoor
    01/01/2000 01:00,30,25
    01/01/2000 02:00,31,26
    01/01/2000 03:00,33,24
    02/01/2000 01:00,29,25
    02/01/2000 02:00,27,26
    02/01/2000 03:00,39,24
    12/01/2000 02:00,27,26
    12/01/2000 03:00,39,24
    12/31/2000 23:00,28,25"
    con <- textConnection(Lines1)
    z <- read.zoo(con, header=TRUE, sep=",",
        format="%m/%d/%Y %H:%M", FUN=as.POSIXct)
    close(con)
    
    zz <- merge(z, Month=.indexmon(z),
        OutdoorAVE=ave(z[,1], .indexmon(z), FUN=mean))
    zz
    #                     Outdoor Indoor Month OutdoorAVE
    # 2000-01-01 01:00:00      30     25     0   31.33333
    # 2000-01-01 02:00:00      31     26     0   31.33333
    # 2000-01-01 03:00:00      33     24     0   31.33333
    # 2000-02-01 01:00:00      29     25     1   31.66667
    # 2000-02-01 02:00:00      27     26     1   31.66667
    # 2000-02-01 03:00:00      39     24     1   31.66667
    # 2000-12-01 02:00:00      27     26    11   31.33333
    # 2000-12-01 03:00:00      39     24    11   31.33333
    # 2000-12-31 23:00:00      28     25    11   31.33333
    

    更新:如何使用两个不同的数据集得到上述结果。

    Lines2 <- "Date,Month,OutdoorAVE
    01/01/2000,Jan,31.33
    02/01/2000,Feb,31.67
    12/01/2000,Dec,31.33"
    con <- textConnection(Lines2)
    z2 <- read.zoo(con, header=TRUE, sep=",", format="%m/%d/%Y",
        FUN=as.POSIXct, colClasses=c("character","NULL","numeric"))
    close(con)
    
    zz2 <- na.locf(merge(z1, Month=.indexmon(z1), OutdoorAVE=z2))[index(z1)]
    # same output as zz (above)
    

    【讨论】:

    • @ery:请看我的编辑。我不确定为什么 Month 总是 11... 也许您的示例数据和实际数据不同?
    【解决方案3】:

    这与您的问题无关,但您可能希望使用RSQLite 和一个单独的表来代替各种聚合值,并使用简单的 SQL 命令连接这些表。如果您使用多种聚合,您的数据框很容易变得又大又丑。

    【讨论】:

    • 这是一个很好的解决方案,但我什至不知道如何在 SQLite 中导入日期/时间,更不用说按月或天分组了。有什么帮助吗?
    • 你的整个问题都可以用 SQL 来解决。我并不是说您应该使用 SQL 进行聚合,但了解它的工作原理很有用(相当简单)。我建议您阅读并在单独的线程中提出您的问题。
    猜你喜欢
    • 2013-07-24
    • 1970-01-01
    • 2015-08-12
    • 2014-11-07
    • 1970-01-01
    • 2015-06-28
    • 2016-01-13
    • 2022-12-24
    • 1970-01-01
    相关资源
    最近更新 更多