绘制多个系列的Pointwise Max

时间:2011-07-09 14:50:11

标签: r

我有一个我导入的csv,它有一个时间序列的多个数据字段。所以第一个字段是日期时间,其余字段是各种数据点。

如何绘制多个字段的逐点最大值,其中字段将在某种通配符上匹配?

例如:

time,foo1,foo2,foo3
1:00,1,2,3
2:00,3,1,1
3:00,2,5,3

最简单的方法是绘制foo.*,以便从每个字段获得最大值:I.e。从这个例子得到的情节将是:(1:00,3),(2:00,3),(3:00,5)?

澄清这个例子,我的最大分数是**

time,foo1,foo2,foo3
1:00,1,2,*3*
2:00,*3*,1,1
3:00,2,*5*,3

2 个答案:

答案 0 :(得分:6)

假设您的数据位于data.frame x中,您可以使用pmax,如下所示:

cbind(x[,"time"], do.call(pmax, x[,grepl("^foo*",names(x))]))

do.callpmax函数调用x中的每一列作为...参数(第一列除外,通过否定下标删除)。 cbindx的第一列与do.call的结果向量相结合。

请注意,do.call的第二个参数需要是一个列表,而data.frame是一个包含一些额外属性的列表。如果x不是data.frame,则需要将其强制转换为一个(或常规列表)。

答案 1 :(得分:2)

与@Joshua的苗条回答相比,这几乎令人尴尬,但我可能会使用reshape2plyr来解决这个问题,如果我没有得到另一个答案的启发。 melt将数据转换为“长”格式,然后按时间列将ddply组分组并选择最大值。

library(plyr)
library(reshape2)


dat <- data.frame(time = 1:3, foo1 = c(1,3,2), foo2 = c(2,1,5), foo3 = c(3,1,3))
dat.m <- melt(dat, id.vars = "time")
ddply(dat.m, "time", summarize, max = max(value))
  time max
1    1   3
2    2   3
3    3   5

测试证实约书亚的答案快了约30倍。我的解决方案唯一合理的好处是它可能更容易理解,但这是非常主观的。结果:

library(rbenchmark)
f_svelte <- function(dat){
  cbind(dat[,1], do.call(pmax, dat[,-1]))

}

f_fat <- function(dat) {
  dat.m <- melt(dat, id.vars = "time")
  ddply(dat.m, "time", summarize, max = max(value))  
}

benchmark(f_svelte(dat), f_fat(dat)
          , columns = c("test", "elapsed", "relative")
          , order = "relative"
          , replications = 500
          )

           test elapsed relative
1 f_svelte(dat)    0.11  1.00000
2    f_fat(dat)    3.59 32.63636