将不同级别的最大值添加到data.frame中的新列

时间:2013-04-24 14:48:59

标签: r matrix dataframe apply

我有以下R问题。我做了一个实验,观察了一些车速。我有一个带汽车的桌子(其中1号表示例如Porche,2表示沃尔沃等)和它们的速度。一辆汽车不止一次被带入观察。因此,例如,保时捷被观察到树木时代,沃尔沃两次。

exp<-data.frame(car=c(1,1,1,2,2,3),speed=c(10,20,30,40,50,60))

我想添加第三列,其中每行/每辆车计算最大速度。所以它看起来像是:

exp<-data.frame(car=c(1,1,1,2,2,3),speed=c(10,20,30,40,50,60), maxSpeed=c(30,30,30,50,50,60))

保时捷的最高观察速度为30,因此保时捷的每一行都将获得maxSpeed = 30.

我知道应该应用/ sapply函数,但不知道如何实现它。任何人? :)

3 个答案:

答案 0 :(得分:2)

@Arun这是我更大样本的结果(1000条记录)。中位数的比率现在(实际上)为0.82:

exp <- data.frame(car=sample(1:10, 1000, T),speed=rnorm(1000, 20, 5))

f1 <- function() mutate(exp, maxSpeed = ave(speed, car, FUN=max))
f2 <- function() transform(exp, maxSpeed = ave(speed, car, FUN=max))

library(microbenchmark)
library(plyr)
> microbenchmark(f1(), f2(), times=1000)
Unit: microseconds
 expr     min      lq  median       uq      max neval
 f1() 551.321 565.112 570.565 589.9680 27866.23  1000
 f2() 662.933 683.138 689.552 713.7665 28510.24  1000

plyr文档本身说Mutate seems to be considerably faster than transform for large data frames.

然而,对于这种情况,你可能是对的。如果我放大样本:

> exp <- data.frame(car=sample(1:1000, 100000, T),speed=rnorm(100000, 20, 5))
> microbenchmark(f1(), f2(), times=100)
Unit: milliseconds
 expr      min       lq   median       uq      max neval
 f1() 37.92438 39.00056 40.66607 41.18115 77.41645   100
 f2() 39.47731 40.28650 43.11927 43.70779 78.34878   100

比率接近1。说实话,我非常肯定plyr性能(总是在我的代码中依赖它),这就是我在评论中“声明”的原因。可能在不同的情况下它表现得更好......

编辑:

使用@Arun评论中的f3()

> microbenchmark(f1(), f2(), f3(), times=100)
Unit: milliseconds
 expr      min       lq   median       uq      max neval
 f1() 38.76050 39.57129 41.48728 42.14812 76.94338   100
 f2() 40.38913 41.19767 44.12329 44.78782 79.94021   100
 f3() 38.63606 39.58700 40.24272 42.04902 76.07551   100

是的!稍快一点......移动的数据会减少?

答案 1 :(得分:2)

非常直截了当data.table

library(data.table)

exp <- data.table(exp)
exp[, maxSpeed := max(speed), by=car]

给出:

exp
   car speed maxSpeed
1:   1    10       30
2:   1    20       30
3:   1    30       30
4:   2    40       50
5:   2    50       50
6:   3    60       60

答案 2 :(得分:1)

transform(exp, maxSpeed = ave(speed, car, FUN=max))

使用split的另一种方式:

exp$maxSpeed <- exp$speed
split(exp$maxSpeed, exp$car) <- lapply(split(exp$maxSpeed, exp$car), max)
exp