0

我已经在这里待了几个小时,似乎找不到解决方案。我有一个非常大的数据框(超过 150 万行),我想做一个相当具体的操作。首先,我的数据如下所示:

STATION       DATE      Precip
COOP 310     -7788        .24
COOP 310     -7788        .15
COOP 310     -6654        .59
COOP 310     -6654        .10
COOP 499     -7122        .64
COOP 499     -7122        .36
COOP 499     -7122        .14
COOP 499     -2350        .11
COOP 499     -2350        .85

我有一个气象站 ID (STATION)、一个 UNIX 纪元形式的日期 (DATE) 和降水值(下雨时的 15 分钟数据间隔)。我一直在尝试做的是确定每个站点每天下雨的每日降雨量总和。所需的输出如下所示:

STATION       DATE        24-hour_PRECIP
COOP 310     -7788        0.39
COOP 310     -6654        0.69
COOP 499     -7122        1.14
COOP 499     -2350        0.96

我认为,这实质上意味着执行SPLIT两次操作,一次根据相同的 STATION 值拆分所有数据,然后再次根据相同的 DATE 值。理论上,此输出将通过一个SAPPLY操作运行,将SUM函数应用于每个唯一日期/站点集中的数据集。我的方法(虽然错误):

数据框名称为“dfhour”:

sp1<-split(dfhour$Precip,dfhour$STATION)

我可以对这些数据执行 sapply 函数,但我想在使用 sapply 之前进一步拆分它。我知道做类似的事情

sapply(split(split(dfhour$Precip, dfhour$STATION),dfhour$DATE),FUN=sum)

将不起作用,因为函数的输出split是列表,并且下一个split函数将无法接受列表作为参数。有人对这个问题有任何指导吗?还有哪些其他功能可以帮助我到达我需要去的地方?

4

3 回答 3

2

我想你只是在寻找aggregate. 如果您的 data.frame 被命名为“mydf”:

> aggregate(Precip ~ ., mydf, sum)
   STATION  DATE Precip
1 COOP 310 -7788   0.39
2 COOP 499 -7122   1.14
3 COOP 310 -6654   0.69
4 COOP 499 -2350   0.96

但是,从数据的大小来看,您可能希望data.table改用:

> library(data.table)
data.table 1.8.8  For help type: help("data.table")
> DT <- data.table(mydf, key = "STATION,DATE")
> DT[, list(Precip = sum(Precip)), by = key(DT)]
    STATION  DATE Precip
1: COOP 310 -7788   0.39
2: COOP 310 -6654   0.69
3: COOP 499 -7122   1.14
4: COOP 499 -2350   0.96

更新,根据评论中的讨论

想象一下您的数据如下(注意重复的日期,但在不同的站点):

mydf <- structure(list(STATION = c("COOP 310", "COOP 310", "COOP 310",                 
     "COOP 310", "COOP 499", "COOP 499", "COOP 499", "COOP 499", "COOP 499",            
     "COOP 499", "COOP 499"), DATE = c(-7788L, -7788L, -6654L, -6654L,                  
     -7122L, -7122L, -7122L, -2350L, -2350L, -7788L, -7788L), Precip = c(0.24,          
     0.15, 0.59, 0.1, 0.64, 0.36, 0.14, 0.11, 0.85, 0.35, 0.17)), .Names = c("STATION", 
     "DATE", "Precip"), row.names = c(NA, 11L), class = "data.frame")
mydf
#     STATION  DATE Precip
# 1  COOP 310 -7788   0.24
# 2  COOP 310 -7788   0.15
# 3  COOP 310 -6654   0.59
# 4  COOP 310 -6654   0.10
# 5  COOP 499 -7122   0.64
# 6  COOP 499 -7122   0.36
# 7  COOP 499 -7122   0.14
# 8  COOP 499 -2350   0.11
# 9  COOP 499 -2350   0.85
# 10 COOP 499 -7788   0.35
# 11 COOP 499 -7788   0.17

提出的两种备选方案都将为“STATION”和“DATE”的组合生成总和。下面是data.table过程和结果:

DT <- data.table(mydf, key = "STATION,DATE")
DT[, list(Precip = sum(Precip)), by = key(DT)]
#     STATION  DATE Precip
# 1: COOP 310 -7788   0.39
# 2: COOP 310 -6654   0.69
# 3: COOP 499 -7788   0.52
# 4: COOP 499 -7122   1.14
# 5: COOP 499 -2350   0.96
于 2013-04-29T17:55:07.880 回答
1

“超过 150 万行”结合简单的拆分应用组合建议data.table是解决您问题的完美工具。

我想你会想要这样的东西:

DT[,sum(Precip),by="STATION,DATE"]

DT的. data.table_data.frame

于 2013-04-29T17:57:40.623 回答
0

您不需要嵌套的splits. 您只需要提供一个捕获交叉级别的“拆分”参数,也许使用该interaction函数。

tapply( statfrm$Precip, interaction(statfrm$STATION, statfrm$DATE) , sum) 
#----------------
COOP-310.-7788 COOP-499.-7788 COOP-310.-7122 COOP-499.-7122 COOP-310.-6654 
          0.39             NA             NA           1.14           0.69 
COOP-499.-6654 COOP-310.-2350 COOP-499.-2350 
            NA             NA           0.96 

您还可以使用 split-sapply 策略来获得类似的答案,并且在您的案例中,零值可能比您使用 tapply 获得的 NA 更合适:

 sapply(split(statfrm$Precip, interaction(statfrm$STATION, statfrm$DATE) ), sum) 
#-------
COOP-310.-7788 COOP-499.-7788 COOP-310.-7122 COOP-499.-7122 COOP-310.-6654 
          0.39           0.00           0.00           1.14           0.69 
COOP-499.-6654 COOP-310.-2350 COOP-499.-2350 
          0.00           0.00           0.96 

至于这个向量的显示,我有时将 as.matrix 包裹在一个向量周围以显示“向下”:

as.matrix(sapply(split(statfrm$Precip, interaction(statfrm$STATION, statfrm$DATE) ), sum))
#_________________
               [,1]
COOP-310.-7788 0.39
COOP-499.-7788 0.00
COOP-310.-7122 0.00
COOP-499.-7122 1.14
COOP-310.-6654 0.69
COOP-499.-6654 0.00
COOP-310.-2350 0.00
COOP-499.-2350 0.96
于 2013-04-29T18:06:07.570 回答