R:如何对纵向数据进行排序

R: how to rank longitudinal data

> dput(subset)
structure(list(MEMORY1 = c(1L, 1L, 1L, 1L, 2L), MEMORY2 = c(1L, 
1L, 1L, 1L, 1L), MEMORY3 = c(1L, 2L, 1L, 1L, 1L), MEMORY4 = c(2L, 
2L, 2L, 2L, 2L), MEMORY5 = c(1L, 2L, 1L, 2L, 1L), MEMORY6 = c(1L, 
1L, 2L, 1L, 2L), MEMORY7 = c(2L, 2L, 2L, 2L, 1L), MEMORY8 = c(1L, 
1L, 1L, 1L, 1L)), .Names = c("MEMORY1", "MEMORY2", "MEMORY3", 
"MEMORY4", "MEMORY5", "MEMORY6", "MEMORY7", "MEMORY8"), row.names = c(NA, 
-5L), class = "data.frame")

> subset
  MEMORY1 MEMORY2 MEMORY3 MEMORY4 MEMORY5 MEMORY6 MEMORY7 MEMORY8
1       1       1       1       2       1       1       2       1
2       1       1       2       2       2       1       2       1
3       1       1       1       2       1       2       2       1
4       1       1       1       2       2       1       2       1
5       2       1       1       2       1       2       1       1

我的数据有 8 个项目(列)以 5 个时间间隔(行)记录。我想按如下方式对数据进行排名:1) 如果列全为 1,则该列的排名为 8。2) 列的排名取决于大于 1 的数字首次出现的时间(对于 MEMORY1,它将是 5, MEMORY3 为 2,MEMORY4 为 1,依此类推)。我编写了以下循环来执行此操作。

ranks = rep(0, 8)
for(i in 1:8){
  v = which(subset[i] > 1)
  if(length(v) == 0){
    ranks[i] = 8
  }else ranks[i] = v[1]
}
> ranks
[1] 5 8 2 1 2 3 1 8

工作正常,但我意识到由于有联系,即 MEMORY4 和 MEMORY7 都排名为 1,那么我希望 MEMORY3 和 MEMORY5 排名为 3 而不是 2。在这种情况下,MEMORY6 应该排名作为 5,而不是 3。所以期望的排名应该是。

6 8 3 1 3 5 1 8

一个选项是使用 sapply 遍历 'df1' 的列并获取值大于 1 的第一个位置。如果没有大于 1 的值,它将是 NA。然后,我们得到 'indx' 的 rank,将 ties.method 指定为 min ('indx1')。 'indx' 中 NA 值的位置被 8 替换为最后一步。

 indx <- sapply(df1, function(x) which(x>1)[1L])
 indx1 <- as.vector(rank(indx, ties.method='min'))
 indx1[is.na(indx)] <- 8
 indx1
 #[1] 6 8 3 1 3 5 1 8