我有一个我导入的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
答案 0 :(得分:6)
假设您的数据位于data.frame x
中,您可以使用pmax
,如下所示:
cbind(x[,"time"], do.call(pmax, x[,grepl("^foo*",names(x))]))
do.call
将pmax
函数调用x
中的每一列作为...
参数(第一列除外,通过否定下标删除)。 cbind
将x
的第一列与do.call
的结果向量相结合。
请注意,do.call
的第二个参数需要是一个列表,而data.frame是一个包含一些额外属性的列表。如果x
不是data.frame,则需要将其强制转换为一个(或常规列表)。
答案 1 :(得分:2)
与@Joshua的苗条回答相比,这几乎令人尴尬,但我可能会使用reshape2
和plyr
来解决这个问题,如果我没有得到另一个答案的启发。 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