我有一个具有以下结构的数据框
输入
set.seed(5)
df <- data.frame(A= round(runif(6,0,100)),B= round(runif(6,0,100)),C= round(runif(6,0,100)),D= round(runif(6,0,100)))
A B C D
1 20 53 32 55
2 69 81 56 84
3 92 96 26 89
4 28 11 20 72
5 10 27 39 21
6 70 49 89 23
现在,我想添加两列,每列分别具有行的第二和第三大元素。
输出
A B C D thirdLarge secLarge
1 20 53 32 55 32 53
2 69 81 56 84 69 81
3 92 96 26 89 89 92
4 28 11 20 72 20 28
5 10 27 39 21 21 27
6 70 49 89 23 49 70
我尝试通过一个简单的“ for循环”执行此操作,但这效率不够高,并且永久占用700000行。
答案 0 :(得分:3)
我们可以使用apply
:
df[c('thirdLarge', 'secLarge')] <- t(apply(df, 1, function(x)
sort(x)[c(length(x)-2, length(x) - 1)]))
#This is shorter
df[c('thirdLarge', 'secLarge')] <- t(apply(df, 1, function(x)
sort(x, decreasing = TRUE)[3:2]))
df
# A B C D thirdLarge secLarge
#1 20 53 32 55 32 53
#2 69 81 56 84 69 81
#3 92 96 26 89 89 92
#4 28 11 20 72 20 28
#5 10 27 39 21 21 27
#6 70 49 89 23 49 70
按照@Chris Ruehlemann的建议使用rank
,但是如果连续两个相同的值,这将失败。
df[c('secLarge', 'thirdLarge')] <- t(apply(df, 1, function(x)
x[rank(-x) %in% 2:3]))
答案 1 :(得分:3)
如果速度是一个问题,请签出 Rfast 软件包:
library(Rfast)
library(dplyr)
mutate(df,
lrg.2 = rownth(as.matrix(df), elems=rep(2, nrow(df)), descending=TRUE),
lrg.3 = rownth(as.matrix(df), elems=rep(3, nrow(df)), descending=TRUE))
A B C D lrg.2 lrg.3
1 20 53 32 55 53 32
2 69 81 56 84 81 69
3 92 96 26 89 92 89
4 28 11 20 72 28 20
5 10 27 39 21 27 21
6 70 49 89 23 70 49
对于包含700,000行的数据帧,这需要<1秒。使用套用需要30秒钟以上。
答案 2 :(得分:0)
看看我是否可以制作不需要for(Node *node: nodes){
std::cout << node->value << "-->" << node->parentTree->id << '\n';
的更快的基本版本:
基本上,我按apply
排序一次并递减值,然后将其反馈回row
并接受必填列:
matrix
使用udf <- unlist(df)
mat <- matrix(udf[order(row(df), -udf)], ncol=ncol(df), byrow=TRUE)
df[c('thirdLarge','secLarge')] <- mat[,3:2]
## A B C D thirdLarge secLarge
##1 20 53 32 55 32 53
##2 69 81 56 84 69 81
##3 92 96 26 89 89 92
##4 28 11 20 72 20 28
##5 10 27 39 21 21 27
##6 70 49 89 23 49 70
df <- df[rep(1:6, 116667),]
## 700,002 rows
system.time({
udf <- unlist(df)
mat <- matrix(udf[order(row(df), -udf)], ncol=ncol(df), byrow=TRUE)
df[c('thirdLarge','secLarge')] <- mat[,3:2]
})
## user system elapsed
## 0.971 0.000 0.972
比较循环遍历:
apply