【问题标题】:Order dataframe based on inherent values within column根据列内的固有值对数据框进行排序
【发布时间】:2018-08-09 23:35:55
【问题描述】:

我想捕获数据框中的固有值,然后根据每列和每行中的事件数将列和行从降序排列到升序。

样本数据

 #A tibble: 26 x 9
   sample_id Gene_A Gene_B Gene_C Gene_D Gene_E Gene_F Gene_G Gene_H
   <fct>      <int>  <int>  <int>  <int>  <int>  <int>  <int>  <int>
 1 A             -1      0      0      0     -1      0      0     -1
 2 B              1      0     -1      1     -1     -1     -1      0
 3 C              1      0     -1      0      1      0      0     -1
 4 D             -1      0      0     -1      1      1     -1      1
 5 E              1      1      1      1     -1      1     -1      0
 6 F             -1     -1      1      1      1     -1      0      0
 7 G              0      0     -1     -1      0     -1      0     -1
 8 H              1      1      1      0      1     -1     -1      0
 9 I              0     -1     -1     -1      0     -1      0      1
10 J             -1      0      0      1     -1     -1      0      1
# ... with 16 more rows

我想要的最终结果是一个按以下层次结构排序的表:

  • 基于具有最多事件到最少事件的基因数量
    • 然后,根据从大多数事件到最少事件的每个 sample_id 的事件数。

这是示例输出:

# A tibble: 26 x 9
   sample_id Gene_B Gene_G Gene_H Gene_A Gene_C Gene_D Gene_F Gene_E
 * <chr>      <int>  <int>  <int>  <int>  <int>  <int>  <int>  <int>
 1 A              0      0     -1     -1      0      0      0     -1
 2 U              0     -1      0      0      0     -1      0      1
 3 C              0      0     -1      1     -1      0      0      1
 4 G              0      0     -1      0     -1     -1     -1      0
 5 W              0     -1      1      1      0      1      0      0
 6 Y              0      0      1      1      0      1      1      0
 7 I             -1      0      1      0     -1     -1     -1      0
 8 J              0      0      1     -1      0      1     -1     -1
 9 O              0      1      0      0      1     -1      1      1
10 P              1     -1     -1      0     -1      0      0     -1
# ... with 16 more rows

我的第一个想法是取绝对总和并为每个样本添加一列总计,取绝对总和并为每列添加一行总计,然后使用顺序。

生成样本数据

dummy.tb <- tibble (sample_id = (sample (1:30,30)), Gene_A = (sample
(-1:1,30, replace = T)), Gene_B = (sample (-1:1,30, replace = T)))

dummy1.tb <- tibble (Gene_C = (sample (-1:1,30, replace = T)), Gene_D
= (sample (-1:1,30, replace = T)), Gene_E = (sample (-1:1,30, replace = T)))

dummy2.tb <- tibble (Gene_F = (sample (-1:1,30, replace = T)), Gene_G
= (sample (-1:1,30, replace = T)), Gene_H = (sample (-1:1,30, replace = T)))

dummy.tb <- cbind.data.frame(dummy.tb, dummy1.tb, dummy2.tb)

dummy.genes <- c ("Gene_A", "Gene_B", "Gene_C", "Gene_D", "Gene_E",
"Gene_F", "Gene_G", "Gene_H")

dummy.total <- as.data.frame (dummy.total)

添加 Col_Total 和列总和

dummy.total <- dummy.tb %>% bind_rows(summarise_all(., funs(if(is.numeric(.)) sum(abs(.)) else "Col_Total")))

dummy.total <- as.data.frame (dummy.total)

按列排序

dummy.total <- dummy.total [,order(dummy.total[nrow(dummy.total),], decreasing = FALSE)]

删除 Col_Total 行

dummy.total <- dummy.total %>% filter (!sample_id == "Col_Total")

dummy.total <- as.data.frame (dummy.total)

添加行总计和行总和

dummy.total <- dummy.total %>% mutate (Row_Total = rowSums (abs((select (., one_of(dummy.genes))))))

dummy.total <- as.data.frame (dummy.total)

按行排序

dummy.total <- dummy.total [order (dummy.total [,ncol(dummy.total)], decreasing = FALSE),]

删除 Row_Total 列

dummy.total <- dummy.total %>% select (-Row_Total)

使用 sample_id 重新排序

dummy.total <- dummy.total %>% select (sample_id, everything())

dummy.total <- as.tibble(dummy.total)

此代码确实有效并提供了所需的输出,但它似乎过于冗长,沿途结构发生了很多变化。使用 tidyverse 或其他方法有什么建议吗?我尝试使用 arrange () 而不是 order 来根据 Col_Total 上的值对列进行排序,但似乎没有用。

注意:它是每个事件,而不仅仅是一个直接的总和,因此包含绝对值来计算事件的数量。

【问题讨论】:

  • 请更正引号。它给出了错误
  • 更改了 dummy.genes 的引号

标签: r sorting dplyr


【解决方案1】:

对于这个问题,matrix 更适合您处理同质(数字)数据。如果将列名和sample_id 分配给dimnamesmatrix,您将能够在排序后保留列和行标识符。

我建议您使用set.seed,这样您的示例将是可重现的,并且可以使用所需的输出验证答案。

请看下图:

set.seed(123)
n <- 30
m <- 9
mat <- matrix(
  sample(-1:1, n * m, replace = TRUE), 
  nrow = n,   
  dimnames = list(1:n, paste("Gene", LETTERS[1:m], sep = "_"))
)
foo <- mat[, order(colSums(abs(mat)))]
bar <- foo[order(rowSums(abs(foo))), ]
head(bar)

输出:

   Gene_F Gene_D Gene_I Gene_G Gene_C Gene_A Gene_H Gene_B Gene_E
18     -1      0      0      0      0     -1      0      0      1
15      0      0      0      1      0     -1     -1     -1      0
27      0      0      0      0      1      0     -1     -1     -1
1       1     -1      0      1      0     -1      0      1      0
3       0      0     -1      1      0      0     -1      1     -1
6       0     -1      1      0      0     -1      1      0      1

【讨论】:

    猜你喜欢
    • 2020-05-15
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    • 2012-09-03
    • 2020-02-29
    • 1970-01-01
    • 2020-08-04
    • 2015-01-05
    相关资源
    最近更新 更多