根据首次发病对数据进行排名

时间:2015-10-01 04:57:29

标签: r algorithm rank

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

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

我有4个时间点(4行)的8个记忆项目的数据集。我试图按照第一次开始对存储器项进行排序,这被定义为第一次存储器项具有值> 1。 1.

对于上述subset,第1,2,3,4,5和7项的排名为1,因为在时间1,这些项的值为&gt; 1.对于项目6和8,它们的值在所有4个时间点都是1,所以我会为它们分配NA的等级。

ranks = rep(0, items)
ranks = sapply(subset, function(x) which(x > 1)[1L])
ranks
# MEMORY1 MEMORY2 MEMORY3 MEMORY4 MEMORY5 MEMORY6 MEMORY7 MEMORY8 
#       1       1       1       1       1      NA       1      NA 

但是,由于MEMORY1MEMORY2的值为1MEMORY3MEMORY4MEMORY5和{{{ 1}}在MEMORY7时间值为2,我想在其他四个项目之前排名1MEMORY1。所以我想要一个看起来像

的输出
MEMORY2

所以1)首先排名2)排名最高值的项目为1,下一个最高值为2,等等。

如何完成第2步?

2 个答案:

答案 0 :(得分:0)

这为您提供了值:

wheremax <- sapply(subset,function(x) { which(x > 1)[1L] }) #your code
as.matrix(subset)[cbind(wheremax,1:ncol(subset))]
[1]  3  3  2  2  2 NA  2 NA

然后您可以获得排名:

DTrank <- rank(-as.matrix(subset)[cbind(wheremax,1:ncol(subset))] + wheremax * max(subset), ties.method = "min", na.last = "keep")
[1]  1  1  3  3  3 NA  3 NA

这会对每个额外的行添加一个惩罚,等于data.frame中任何位置的最大值。它确保第二行中的值始终排在第一行的值

之下

但它没有按增量排序(即1,2,3,......)。但是,较高的数字总是具有较低的值。如果有更好的方法,请接受建议。

答案 1 :(得分:0)

首先,获得等级的等级:

  df <- sapply(subset, function(x) {
  tmp <- which(x > 1)[1L]; 
  c(rank=tmp, val=ifelse(length(tmp>0), x[tmp], NA))
})

# adding "memory" field to keep track of the memories
df <- data.frame(t(df), memory=1:nrow(df))

# let's add a little excitement otherwise hard to tell if it's working
df[3,1] <- 2
# dealing with NA by giving them infinite rank
df[is.na(df)] <- Inf
# val will be sorted by increasing values, so take the neg because we want them decreasing 
df$val <- -df$val
final_rank_order <- order(df$rank, df$val, decreasing = F)
df <- df[final_rank_order,]

df$final <- 1
for(i in 2:nrow(df)) {
  if(df$rank[i]==df$rank[i-1] & df$val[i]==df$val[i-1])
    df$final[i] <- df$final[i-1]
  else 
    df$final[i] <- df$final[i-1]+1
}

此时我们有这个:

> df
        rank  val memory final
MEMORY1    1   -3      1     1
MEMORY2    1   -3      2     1
MEMORY4    1   -2      4     2
MEMORY5    1   -2      5     2
MEMORY7    1   -2      7     2
MEMORY3    2   -2      3     3
MEMORY6  Inf -Inf      6     4
MEMORY8  Inf -Inf      8     4

最后的触摸:

final_ranks <- df$final[order(df$memory)]

> final_ranks
[1] 1 1 3 2 2 4 2 4

我无法相信它必须如此hacky。它起初真的以为它是微不足道的。必须有更好的方法!

请注意,由于您只有1和NA,因此我更改了您的数据,因此无法判断代码是否正常工作。