还有一个要求 - 结果向量与原始向量的顺序相同.
我有一个非常基本的功能,可以对矢量进行百分位数,并且按照我希望的方式工作:
ptile <- function(x) {
p <- (rank(x) - 1)/(length(which(!is.na(x))) - 1)
p[p > 1] <- NA
p
}
data <- c(1, 2, 3, 100, 200, 300)
Run Code Online (Sandbox Code Playgroud)
例如,ptile(data)生成:
[1] 0.0 0.2 0.4 0.6 0.8 1.0
Run Code Online (Sandbox Code Playgroud)
我真正希望能够做的是使用相同的功能(ptile)并让它在一个因素的水平范围内工作.所以假设我有一个"因素"如下:
f <- as.factor(c("a", "a", "b", "a", "b", "b"))
Run Code Online (Sandbox Code Playgroud)
我希望能够将"数据"转换为一个向量,告诉我,对于每个观察,它相应的百分位数相对于同一级别内的其他观察值是什么,如下所示:
0.0 0.5 0.0 1.0 0.5 1.0
Run Code Online (Sandbox Code Playgroud)
在黑暗中拍摄,我试过:
tapply(data,f,ptile)
Run Code Online (Sandbox Code Playgroud)
事实上,它确实成功地进行了排名/百分比,但这样做是因为我不知道哪些观察结果与原始向量中的索引相匹配:
[1] a a b a b b
Levels: a b
> tapply(data,f,ptile)
$a
[1] 0.0 0.5 1.0
$b
[1] 0.0 0.5 1.0
Run Code Online (Sandbox Code Playgroud)
这很重要,因为我正在使用的实际数据可以有1000-3000个观测值(股票)和10-55个等级(像扇区,其他股票特征分组等),我需要得到的矢量相同按顺序排列,以便在我的矩阵中逐行排列所有内容.
是否有一些"应用"变体会做我想要的?或者一些快速的线路可以做到这一点?我已经在C#和F#中编写了这个功能,并且有更多的代码行,但是我认为在R中必须有一些非常直接,优雅的解决方案.在那儿?
提前致谢!
42-*_*42- 11
ave功能非常有用.主要问题是要记住,您始终需要使用以下命令命名该函数FUN=:
dt <- data.frame(data, f)
dt$rank <- with(dt, ave(data, list(f), FUN=rank))
dt
#---
data f rank
1 1 a 1
2 2 a 2
3 3 b 1
4 100 a 3
5 200 b 2
6 300 b 3
Run Code Online (Sandbox Code Playgroud)
编辑:我以为我在回答标题中的问题但是被要求包含使用"ptile"功能的代码:
> dt$ptile <- with(dt, ave(data, list(f), FUN=ptile))
> dt
data f rank ptile
1 1 a 1 0.0
2 2 a 2 0.5
3 3 b 1 0.0
4 100 a 3 1.0
5 200 b 2 0.5
6 300 b 3 1.0
Run Code Online (Sandbox Code Playgroud)