将R中的每行从最大值重新排列为最小值

将R中的每行从最大值重新排列为最小值,r,sorting,R,Sorting,我的数据框设置如下: Black White Red Blue 0.8 0.1 0.07 0.03 0.3 0.6 0 0.1 0.1 0.6 0.25 0.05 我希望我的数据框看起来像这样: Black White Red Blue Color1 Color2 Color3

我的数据框设置如下:

Black      White       Red       Blue
 0.8        0.1        0.07      0.03
 0.3        0.6         0        0.1
 0.1        0.6        0.25      0.05
我希望我的数据框看起来像这样:

Black      White       Red       Blue     Color1     Color2     Color3    Color4
 0.8        0.1        0.07      0.03      0.8        0.1        0.07      0.03 
 0.3        0.6         0        0.1       0.6        0.3         0.1        0
 0.1        0.6        0.25      0.05      0.6        0.25        0.1      0.05
其中Color1表示每行的最大值,Color2表示第二大值,Color3表示第三大值,Color4表示每行的最小值

到目前为止,我已经使用这个函数来获得我想要的,这是上面的结果:

maxn <- function(n) function(x) order(x, decreasing = TRUE)[n]
df$Color1 <- apply(df, 1, max)
df$Color2 <- apply(df, 1, function(x)x[maxn(3)(x)])
df$Color3 <- apply(df, 1, function(x)x[maxn(4)(x)])
df$Color4 <- apply(df, 1, function(x)x[maxn(5)(x)])


一个选项是使用
排序
应用
转置
,然后使用
cbind
和数据帧作为:

cbind(df, t(apply(df, 1, sort, decreasing = TRUE)))

#   Black White  Red Blue   1    2    3    4
# 1   0.8   0.1 0.07 0.03 0.8 0.10 0.07 0.03
# 2   0.3   0.6 0.00 0.10 0.6 0.30 0.10 0.00
# 3   0.1   0.6 0.25 0.05 0.6 0.25 0.10 0.05
更新:根据@dww的建议,列名可分配为:

df[paste0('color',1:4)] = t(apply(df, 1, sort, decreasing = TRUE))

# Black White  Red Blue color1 color2 color3 color4
# 1   0.8   0.1 0.07 0.03    0.8   0.10   0.07   0.03
# 2   0.3   0.6 0.00 0.10    0.6   0.30   0.10   0.00
# 3   0.1   0.6 0.25 0.05    0.6   0.25   0.10   0.05

一个选项是使用
排序
应用
转置
,然后使用
cbind
和数据帧作为:

cbind(df, t(apply(df, 1, sort, decreasing = TRUE)))

#   Black White  Red Blue   1    2    3    4
# 1   0.8   0.1 0.07 0.03 0.8 0.10 0.07 0.03
# 2   0.3   0.6 0.00 0.10 0.6 0.30 0.10 0.00
# 3   0.1   0.6 0.25 0.05 0.6 0.25 0.10 0.05
更新:根据@dww的建议,列名可分配为:

df[paste0('color',1:4)] = t(apply(df, 1, sort, decreasing = TRUE))

# Black White  Red Blue color1 color2 color3 color4
# 1   0.8   0.1 0.07 0.03    0.8   0.10   0.07   0.03
# 2   0.3   0.6 0.00 0.10    0.6   0.30   0.10   0.00
# 3   0.1   0.6 0.25 0.05    0.6   0.25   0.10   0.05

这相当复杂,但如果处理大量行,则更快的解决方案是只进行一次排序/排序,然后将其重新插入矩阵形状:

matrix(x[order(-row(x), x, decreasing=TRUE)], nrow=nrow(x), ncol=ncol(x), byrow=TRUE)
一些时间安排:

x <- matrix(rnorm(300000*5), nrow=300000, ncol=5)
system.time(t(apply(x, 1, sort, decreasing=TRUE)))
#   user  system elapsed 
#  14.13    0.00   14.13 
system.time(
  matrix(x[order(-row(x),x, decreasing=TRUE)], nrow=nrow(x), ncol=ncol(x), byrow=TRUE)
)
#   user  system elapsed 
#   0.10    0.00    0.09 

x这有点复杂,但如果处理大量行,一个更快的解决方案是只进行一次排序/排序,然后将其重新插入矩阵形状:

matrix(x[order(-row(x), x, decreasing=TRUE)], nrow=nrow(x), ncol=ncol(x), byrow=TRUE)
一些时间安排:

x <- matrix(rnorm(300000*5), nrow=300000, ncol=5)
system.time(t(apply(x, 1, sort, decreasing=TRUE)))
#   user  system elapsed 
#  14.13    0.00   14.13 
system.time(
  matrix(x[order(-row(x),x, decreasing=TRUE)], nrow=nrow(x), ncol=ncol(x), byrow=TRUE)
)
#   user  system elapsed 
#   0.10    0.00    0.09 

x或要在同一步骤中轻松添加列名,
df[paste0('color',1:4)]=t(apply(df,1,sort,discreating=t))
@dww极好的建议。我应该把它作为我答案的一部分添加进去。或者,为了在同一步骤中轻松添加列名,
df[paste0('color',1:4)]=t(apply(df,1,sort,discreating=t))
@dww非常好的建议。我应该把它作为我回答的一部分。