在R中排序排序

时间:2016-03-09 12:15:02

标签: r

我想如何使用R在csv中进行行方式排序。这里有以下数据

Name  English Math  French
John    56    78    86
Sam     79    97    86
Viru    93    44    34

我想对上面的数据集执行行方式排序。如下所示。

Name  
John   French  86   Math 78  English 56 
Sam    Math    97   French 86 English 79  
Viru    English 93   Math 44   French 34

请告诉我如何处理

2 个答案:

答案 0 :(得分:7)

如果我们只需按行sort,请applyMARGIN=1一起使用,并在转置输出后将输出分配回原始列。

df1[-1] <- t(apply(df1[-1], 1, 
        FUN=function(x) sort(x, decreasing=TRUE)))

df1
#   Name English Math French
# 1 John      86   78     56
# 2  Sam      97   86     79
# 3 Viru      93   44     34

注意:但我们可能需要更改列名,因为按行排序会给出新的排序值。

另一个选项是分别使用apply获取列名和值,Map我们得到相应的列cbind,第一列有输出。< / p>

nMat <- `dim<-`(names(df1)[-1][t(apply(df1[-1], 1,  
        order, decreasing=TRUE))], dim(df1[-1]))
vMat <- t(apply(df1[-1], 1,  sort, decreasing=TRUE))
cbind(df1[1], data.frame(Map(cbind, as.data.frame(nMat,
   stringsAsFactors=FALSE), as.data.frame(vMat))))
#  Name    V1.1 V1.2   V2.1 V2.2    V3.1 V3.2
#1 John  French   86   Math   78 English   56
#2  Sam    Math   97 French   86 English   79
#3 Viru English   93   Math   44  French   34

或另一个选项是data.table。我们melt广泛的&#39;格式为&#39; long&#39;格式,按&#39;名称&#39;分组,我们order&#39;值&#39;在&#39; i&#39;中按降序排列,获取Data.table的子集(.SD),创建一个新列(&#39; N&#39;),按&#39; Name& #39;并使用dcast转换为&#39; long&#39;广泛的&#39;。

library(data.table)
dcast(melt(setDT(df1), id.var='Name')[order(-value), 
  .SD, Name][, N:=paste0("Col", 1:.N) , .(Name)],
    Name~N, value.var=c("variable", "value"))
#   Name variable_Col1 variable_Col2 variable_Col3 value_Col1 value_Col2 value_Col3
#1: John        French          Math       English         86         78         56
#2:  Sam          Math        French       English         97         86         79
#3: Viru       English          Math        French         93         44         34

修改 如果您的10个或更多列包含值,则上述data.table解决方案将无效,因为col10将在排序中位于col2之前,即使更高的值将存储在{{ 1}}。要解决此问题,您只能使用数字作为新列的名称,如下所示:

col2

答案 1 :(得分:4)

您可以尝试:

cbind(x[1],matrix(paste(colnames(x)[apply(x[,2:4],1,order,decreasing=TRUE)+1],
      apply(x[,2:4],1,sort,decreasing=TRUE)),ncol=3,byrow=TRUE))
#  Name          1         2          3
#1 John  French 86   Math 78 English 56
#2  Sam    Math 97 French 86 English 79
#3 Viru English 93   Math 44  French 34