【问题标题】:Rearranging each row from largest value to smallest value in R在R中将每一行从最大值重新排列到最小值
【发布时间】:2018-10-02 21:26:50
【问题描述】:

我的数据框设置如下:

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)])

有没有更简洁的方式来安排我的数据集?

另外,有点跑题了:我不确定是不是因为这是一个 CSV 文件,每当我使用该函数时都会使用它

df$Color2 <- apply(df, 1, function(x)x[maxn(2)(x)])

它将返回与函数相同的结果

apply(df, 1, max)

apply(df, 1, function(x)x[maxn(1)(x)])

【问题讨论】:

    标签: r sorting


    【解决方案1】:

    一种选择是将sortapplytranspose 一起使用,然后将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
    

    【讨论】:

    • 或在同一步骤中轻松添加列名,df[paste0('color',1:4)] = t(apply(df, 1, sort, decreasing=T))
    • @dww 很好的建议。我应该将其添加为我的答案的一部分。
    【解决方案2】:

    如果您要处理大量行,这会稍微复杂一些,但更快的解决方案是只进行一次排序/排序并将其重新插入矩阵形状:

    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 
    

    【讨论】:

      猜你喜欢
      • 2015-01-09
      • 2018-06-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      相关资源
      最近更新 更多