【问题标题】:R: Sort columns of a data frame by a vector of column namesR:按列名向量对数据框的列进行排序
【发布时间】:2014-06-02 05:39:22
【问题描述】:

我有一个如下所示的 data.frame:

其中有 1000 多列名称相似。

我有一个包含这些列名的向量,如下所示:

向量按 cluster_id 排序(最高为 11)。

我想对数据框中的列进行排序,使列按照向量中名称的顺序排列。

我想要的一个简单例子是:

数据:

 A    B    C
 1    2    3
 4    5    6

矢量: c("B","C","A")

排序:

 B    C    A
 2    3    1
 5    6    4

有没有快速的方法来做到这一点?

【问题讨论】:

  • @AnandaMahto 这不是学校作业....除了使用循环之外,我不知道如何对列进行排序并检查列名在向量中的位置,然后对其进行排序制作数据框。
  • 为什么是一张桌子的照片?如果您提供reproducable example,则获得正确答案的机会会大大增加。
  • @Jaap 原始数据太大。我可以给你一个非常简单的例子。检查编辑。
  • 我已经在问题中添加了一个简单的例子。
  • @YilunZhang 您是否阅读过有关可重现示例的帖子?我不是要你的整个数据集。例如,您可以向我们提供您的部分数据的dput。例如:dput(head(df))

标签: r sorting vector dataframe


【解决方案1】:

更新,OP 添加了可重现的数据:

df <- read.table(h=T, text="A    B    C
    1    2    3
    4    5    6")
vec <- c("B", "C", "A")
df[vec]

结果:

  B C A
1 2 3 1
2 5 6 4

如 OP 所愿。


怎么样:

df[df.clust$mutation_id]

其中df 是您要对其列进行排序的data.frame,df.clust 是包含具有列顺序的向量的数据框(mutation_id)。

这基本上将df 视为一个列表,并使用标准矢量索引技术对其进行重新排序。

【讨论】:

  • 所以你向df添加一个新列,一个有序列名的列?那么如何按这个顺序对列进行排序呢?
  • @YilunZhang 我不会向df 添加列。 df[df.clust$mutation_id]df[df.clust$mutation_id, ] 完全不同。第一个实际上与df[,df.clust$mutation_id] 相同(即对列进行排序),原因与数据帧的双重性质(它们既是列表又是数据帧)有关。第二个对行进行排序。
【解决方案2】:

Brodie 的回答完全符合您的要求。但是,您暗示您的数据很大,所以我将提供使用“data.table”的替代方法,它有一个名为setcolorder 的函数,可以通过引用更改列顺序。

这是一个可重现的例子。

从一些简单的数据开始:

mydf <- data.frame(A = 1:2, B = 3:4, C = 5:6)
matches <- data.frame(X = 1:3, Y = c("C", "A", "B"), Z = 4:6)
mydf
#   A B C
# 1 1 3 5
# 2 2 4 6
matches
#   X Y Z
# 1 1 C 4
# 2 2 A 5
# 3 3 B 6

提供证明布罗迪的答案有效的证据:

out <- mydf[matches$Y]
out
#   C A B
# 1 5 1 3
# 2 6 2 4

展示一种更节省内存的方式来做同样的事情。

library(data.table)
setDT(mydf)
mydf
#    A B C
# 1: 1 3 5
# 2: 2 4 6

setcolorder(mydf, as.character(matches$Y))
mydf
#    C A B
# 1: 5 1 3
# 2: 6 2 4

【讨论】:

    【解决方案3】:

    A5C1D2H2I1M1N2O1R2T1 的解决方案不适用于我的数据(我遇到了与张一伦类似的问题)所以我找到了另一种选择:

    mydf <- data.frame(A = 1:2, B = 3:4, C = 5:6)
    #   A B C
    # 1 1 3 5
    # 2 2 4 6
    matches <- c("B", "C", "A") #desired order
    
    mydf_reorder <- mydf[,match(matches, colnames(mydf))]
    colnames(mydf_reorder)
    #[1] "B" "C" "A"
    

    match()求第一个元素在第二个元素上的位置:

    match(matches, colnames(mydf))
    #[1] 2 3 1
    

    如果有人遇到问题,我希望这可以提供另一种解决方案!

    【讨论】:

      猜你喜欢
      • 2011-11-12
      • 2021-10-29
      • 2016-07-28
      • 2018-06-25
      • 2020-04-15
      • 1970-01-01
      • 2018-03-18
      相关资源
      最近更新 更多