6

如果我有一个 data.frame(sum_clus) 有 600 列(变量)和 10 行没有 NA 并且都是数值,我如何创建 5 个新变量来为我提供该行中前 5 个变量的列名?

例如。

max <- apply(sum_clus ,1, max)    
for(ii in 1:10) sum_clus$max[ii] <- colnames(sum_clus)[which(sum_clus[ii , ] 
== sum_clus[ii, sum_clus[ii,] == max[ii]])]

上面的代码帮助我创建了一个变量 sum_clus$max,它为我提供了每行中最大变量的列名。同样,我怎样才能得到 5 个这样的变量来给我前 5 个变量的列名?sum_clus$max、sum_clus$second_but_max 等等。

提前致谢!

4

2 回答 2

5

一种选择是使用order()然后使用它来子集列名,例如:

set.seed(1)
df <- data.frame(matrix(runif(600*10), ncol = 600))

foo <- function(x, names) {
  ord <- order(x, decreasing = TRUE)[1:5]
  names[ord]
}

nams <- colnames(df)
apply(df, 1, foo, names = nams)

生产

> apply(df, 1, foo, names = nams)
     [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]   [,10] 
[1,] "X369" "X321" "X348" "X415" "X169" "X258" "X55"  "X182" "X99"  "X78" 
[2,] "X42"  "X295" "X563" "X173" "X377" "X31"  "X246" "X353" "X259" "X384"
[3,] "X98"  "X440" "X371" "X207" "X429" "X292" "X433" "X437" "X123" "X558"
[4,] "X13"  "X193" "X396" "X78"  "X543" "X228" "X211" "X2"   "X583" "X508"
[5,] "X35"  "X364" "X249" "X33"  "X388" "X405" "X458" "X252" "X569" "X456"

检查这是否有效:

> names(sort(unlist(df[1,, drop = TRUE]), decreasing = TRUE)[1:5])
[1] "X369" "X42"  "X98"  "X13"  "X35" 
> names(sort(unlist(df[2,, drop = TRUE]), decreasing = TRUE)[1:5])
[1] "X321" "X295" "X440" "X193" "X364"

似乎还可以。

于 2013-05-14T19:37:00.967 回答
3

这是一个类似的解决方案,使用 (i) 循环而不是apply; (ii)rank而不是order

set.seed(1)
n_i   = 10
n_ii  = 600
n_top = 5
df <- data.frame(matrix(runif(n_ii*n_i), ncol = n_ii))

out <- matrix("",n_top,n_i)
for (i in 1:n_i){
    colranks <- rank(df[i,])
    out[,i] <- names(sort(colranks)[n_ii:(n_ii-(n_top-1))])
}
#      [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]   [,9]   [,10] 
# [1,] "X369" "X321" "X348" "X415" "X169" "X258" "X55"  "X182" "X99"  "X78" 
# [2,] "X42"  "X295" "X563" "X173" "X377" "X31"  "X246" "X353" "X259" "X384"
# [3,] "X98"  "X440" "X371" "X207" "X429" "X292" "X433" "X437" "X123" "X558"
# [4,] "X13"  "X193" "X396" "X78"  "X543" "X228" "X211" "X2"   "X583" "X508"
# [5,] "X35"  "X364" "X249" "X33"  "X388" "X405" "X458" "X252" "X569" "X456"

单线类似物apply

apply(df,1,function(x)names(sort(rank(x))))[600:596,]
于 2013-05-14T19:37:39.337 回答