代码之家  ›  专栏  ›  技术社区  ›  Rilcon42

查找第二大列名

r
  •  0
  • Rilcon42  · 技术社区  · 6 年前

    我试图找到最大的列值和第二大的列值以及这两列的名称。然而,我正在努力获得第二大列名。

    我试图编写一个lapply函数,该函数将第一个max的值从考虑范围中移除,但它丢弃了列名计数。有什么建议吗?

    temp<-data.frame(c(1,2,3,4),c(1,2,3,1),c(4,5,1,2),c(1,6,5,4),c(2,2,2,2))
    colnames(temp)<-c("c1","c2","c3","c4","c5")
    
    temp$MaxOrders<-as.numeric(apply(temp[,c(-1)],1,function(x){x[which.max(x)]}))
    temp$secondMaxOrders<-as.numeric(apply(temp[,c(2,3,4,5)],1,function(x){x[order(x)[2]]}))
    
    temp$MaxColName<-colnames(temp)[c(-1)][max.col(temp[,c(-1)],ties.method="first")]
    
    temp
    
      c1 c2 c3 c4 c5 MaxOrders secondMaxOrders MaxColName
    1  1  1  4  1  2         4               1         c3
    2  2  2  5  6  2         6               5         c4
    3  3  3  1  5  2         5               3         c4
    4  4  1  2  4  2         4               2         c4
    

    目标:按列名查找第二高的

      c1 c2 c3 c4 c5 MaxOrders secondMaxOrders MaxColName secondMaxColumnName
    1  1  1  4  1  2         4               2         c3 c5
    2  2  2  5  6  2         6               5         c4 c3
    3  3  3  1  5  2         5               3         c4 c2
    4  4  1  2  4  2         4               2         c4 c3
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Ronak Shah    6 年前

    我们可以一个完成 apply 通过查找每行中的2个最大值并返回它们的列名来调用。

    temp[c("MaxOrders", "secondMaxOrders", "MaxColName", "secondMaxColumnName")] <-
        t(apply(temp, 1, function(x) {
             inds <- order(x, decreasing = TRUE)[1:2]
             c(x[inds], names(temp)[inds])
    }))
    
    temp
    #  c1 c2 c3 c4 c5 MaxOrders secondMaxOrders MaxColName secondMaxColumnName
    #1  1  1  4  1  2         4               2         c3                  c5
    #2  2  2  5  6  2         6               5         c4                  c3
    #3  3  3  1  5  2         5               3         c4                  c1
    #4  4  1  2  4  2         4               4         c1                  c4
    

    或者,如果您想完全删除最大值,只考虑剩余的第二个最大值。

    t(apply(temp, 1, function(x) {
        inds <- match(unique(sort(x, decreasing=TRUE))[1:2], x)
        c(x[inds], names(temp)[inds])
    }))
    
    #     [,1] [,2] [,3] [,4]
    #[1,] "4"  "2"  "c3" "c5"
    #[2,] "6"  "5"  "c4" "c3"
    #[3,] "5"  "3"  "c4" "c1"
    #[4,] "4"  "2"  "c1" "c3"
    
        2
  •  2
  •   d.b    6 年前
    temp<-data.frame(c(1,2,3,1),c(4,5,1,2),c(1,6,5,4),c(2,2,2,2))
    colnames(temp)<-c("c2","c3","c4","c5")
    
    m1 = max.col(temp)
    m2 = max.col(t(sapply(seq_along(m1), function(i)
        replace(temp[i,], temp[i,] == temp[i, m1[i]], -Inf))))
    
    max1 = temp[cbind(1:NROW(temp), m1)]
    max2 = temp[cbind(1:NROW(temp), m2)]
    
    data.frame(m1 = colnames(temp)[m1],
               m2 = colnames(temp)[m2],
               max1,
               max2)
    #  m1 m2 max1 max2
    #1 c3 c5    4    2
    #2 c4 c3    6    5
    #3 c4 c2    5    3
    #4 c4 c5    4    2
    
        3
  •  0
  •   jay.sf    6 年前

    你可以用一个键向量,它会给你两个 *Orders *ColName 你能做到的 c 原酸盐:

    key <- setNames(names(temp[1:5]), 1:5)
    nms <- c("MaxOrders", "secondMaxOrders", "MaxColName", "secondMaxColumnName")
    
    d <- t(sapply(seq(nrow(temp)), function(x) {
      o <- order(-temp[x, 2:5])[1:2]
      return(setNames(c(temp[x, o + 1], key[o + 1]), nms))
    }))
    

    这会给你一个理想的结果:

    cbind(temp, d)
    #   c1 c2 c3 c4 c5 MaxOrders secondMaxOrders MaxColName secondMaxColumnName
    # 1  1  1  4  1  2         4               2         c3                  c5
    # 2  2  2  5  6  2         6               5         c4                  c3
    # 3  3  3  1  5  2         5               3         c4                  c2
    # 4  4  1  2  4  2         4               2         c4                  c3
    

    数据

    temp <- structure(list(c1 = c(1, 2, 3, 4), c2 = c(1, 2, 3, 1), c3 = c(4, 5, 1, 2), 
                           c4 = c(1, 6, 5, 4), c5 = c(2, 2, 2, 2)), class = "data.frame", 
                      row.names = c(NA, -4L))