【问题标题】:Find the indices of top n elements in a row after ignoring selected indices忽略选定索引后查找一行中前 n 个元素的索引
【发布时间】:2016-06-29 09:27:02
【问题描述】:

我有一个数据框df1 和一个列表l1,如下所示:

df1 <- data.frame(c1 = c(4.2, 1.2, 3.0) , c2 = c(2.3, 1.8, 12.0 ) ,c3 = c(1.2, 3.2, 2.0 ) , c4 = c(2.2, 1.9, 0.9) )
l1 <- list(x1 = c(2,4) ,x2 = c(3) ,x3 = c(2))

其中 l1 包含 df1 中要忽略的索引列表。 现在,我想在排除列表 l1 中每一行的索引后找到前 2 个(可能更高)元素的索引。实际数据有更多的行和列。 所以,预期的输出是:

[1,]    1 3
[2,]    2 4
[3,]    1 3

df1:

      c1   c2  c3  c4
1    4.2  2.3 1.2 2.2
2    1.2  1.8 3.2 1.9
3    3.0 12.0 2.0 0.9

如果索引可以按照占位符的值的顺序排列,那也很有帮助。那么预期的输出将是:

 [1,]    1 3
 [2,]    4 2
 [3,]    1 3

【问题讨论】:

    标签: r sorting indexing


    【解决方案1】:

    我们可以使用rank

    lapply(seq_len(nrow(df1)), function(i) {
          x1 <- unlist(df1[i,])
          i2 <- l1[[i]]
          i3 <- seq_along(x1) %in% i2
          which(rank(-x1*NA^i3) %in% 1:2) })
    #[[1]]
    #[1] 1 3
    
    #[[2]]
    #[1] 2 4
    
    #[[3]]
    #[1] 1 3
    

    更新

    如果我们需要它在order

    lapply(seq_len(nrow(df1)), function(i) {
      x1 <- unlist(df1[i,])
      i2 <- l1[[i]]
      i3 <- seq_along(x1) %in% i2
      i4 <- which(rank(-x1*NA^i3) %in% 1:2)
      i4[order(-x1[i4])]      
    
        })
    #[[1]]
    #[1] 1 3
    
    #[[2]]
    #[1] 4 2
    
    #[[3]]
    #[1] 1 3
    

    【讨论】:

    • 谢谢,效果很好。现在,如果索引可以按其占位符值的顺序排列,那就太好了。
    • @ViragSwami 感谢您的评论,我已经更新了帖子
    【解决方案2】:

    我对问题的理解如下。对于df1 中的每一行i,排除编号为l1[i] 的元素,然后给出剩余最大两个元素的索引。

    highest.two <- function(x){
      first.highest_position <- which.max(x) 
      second.highest_value <- max(x[-first.highest_position])
      second.highest_position <- which(x == second.highest_value)
      return(c(first.highest_position, second.highest_position))
    }
    
    ret <- matrix(NA, nrow = nrow(df1), ncol = 2)
    for(i in 1:nrow(df1)){
      tmp <- df1[i, ]
      tmp[l1[i][[1]]] <- -Inf
      ret[i, ] <- highest.two(tmp) #if you want to have these indices ordered use sort(highest.two(tmp))
    }
    ret
    

    【讨论】:

    • 您已经正确理解了这个问题。但是数字 2(最多 2 个元素)也可能很高,因此更通用的方法会更好。另外,我希望索引按其各自占位符的顺序排列。
    【解决方案3】:

    同样使用秩但返回一个矩阵。 t() 将 data.frame 转换为矩阵使语法有点难看

    df1 <- data.frame(c1 = c(4.2, 1.2, 3.0) , c2 = c(2.3, 1.8, 12.0 ) ,c3 = c(1.2, 3.2, 2.0 ) , c4 = c(2.2, 1.9, 0.9) )
    l1 <- list(x1 = c(2,4) ,x2 = c(3) ,x3 = c(2))
    
    
    indexOrderSub <- function( df , excl  , top = 2) {
        z <- 1:length(df)
        sel <-  !( z  %in%  excl )
        rz <- z[ sel   ]
        rz2 <- tail( rz[order(  rank(df)[ sel ]   )] , top)
        rz2[order(rz2)]
    }
    
    
    t( mapply( indexOrderSub , as.data.frame(t(df1)) , l1)) 
    

    【讨论】:

      猜你喜欢
      • 2016-10-27
      • 2015-05-07
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      相关资源
      最近更新 更多