我有以下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函数,但不知道如何实现它。任何人? :)
答案 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