从数据框列中选择最高排名

时间:2015-03-30 14:39:04

标签: r

我有一个这样的数据框:

   a  b    c    d    e
1 47Z TS2  TS2  3SU  3SU
2 TS2 47Z  3SU  K5S  47Z
3 3SU A2D  A2D  47Z  A2D
4 FZT 3SU  FZT  FZT  RF9
5 A2D K5S       TS2

每列代表一个功能的排名(此处为a-d)。排名中使用的代码不得出现在每一列中(但它们可以)并且排名的长度不同。在原始文件中,大约有60个排名/列,每个列有10-20个代码。

所以我现在想要选择排名中的前x个代码(在这个例子中x = 2),之前没有选择过两次以上。对于上面的例子,这将是结果:

   a  b    c    d    e
1 47Z TS2  3SU  3SU  A2D
2 TS2 47Z  A2D  K5S  RF9

外观的顺序并不重要。

我必须承认,如果不使用多个for循环,我不知道如何实现它。 谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

这是使用for循环的可能解决方案:

getTopRanking <- function(df,topN=2,maxRep=2){

  uniqueVals <- unique(na.omit(unlist(df)))
  repetitions <- data.frame(count=rep.int(0,length(uniqueVals)),row.names=uniqueVals)

  res <- vector(mode='list',length=ncol(df))
  for(i in 1:ncol(df)){
    colvals <- df[,i]
    topNVals <- head(colvals[colvals %in% 
                             row.names(repetitions)[repetitions$count < maxRep]],topN)
    # pad with NAs (in case we can't find topN elements)
    topNVals <- c(topNVals, rep.int(NA,max(topN-length(topNVals),0)))
    res[[i]] <- topNVals
    repetitions[na.omit(topNVals),1] <- repetitions[na.omit(topNVals),1] + 1
  }
  result <- do.call(cbind.data.frame,res)
  colnames(result) <- colnames(df)
  return(result)
}

用法示例:

# your example data.frame
df <- 
  data.frame(
    a = c("47Z", "TS2", "3SU", "FZT", "A2D"), 
    b = c("TS2", "47Z", "A2D", "3SU", "K5S"), 
    c = c("TS2", "3SU", "A2D", "FZT",  NA), 
    d = c("3SU", "K5S", "47Z", "FZT", "TS2"),
    e = c("3SU", "47Z", "A2D", "RF9",  NA),
    stringsAsFactors=F)

res <- getTopRanking(df,topN=2,maxRep=2)
> res
    a   b   c   d   e
1 47Z TS2 3SU 3SU A2D
2 TS2 47Z A2D K5S RF9