【问题标题】:R: How can I transpose a selection of every 5 rows into a single row?R:如何将每 5 行的选择转换为单行?
【发布时间】:2019-04-17 14:42:00
【问题描述】:

我有以下(整洁)格式的数据集:

SAMPLE, MARKER, ALLELE, LENGTH, PEAK
BRIS01, B100, allele 1, NA, 126.95
BRIS01, B100, allele 2, 160, 159.72
BRIS01, B100, allele 3, 162, 162.01
BRIS02, B100, allele 1, 152, 151.4
BRIS02, B100, allele 2, NA, NA
BRIS02, B100, allele 3, NA, NA

每个样本总共有 14 个标记的条目,每个标记都有 5 个等位基因的条目,即使条目只是“NA”。我不确定有多少样本。

我花了一整天的时间尝试将其重组为以下格式,以便对于每个样本,每个标记的所有等位基因值都彼此相邻,但无济于事:

                MARKER 1                              MARKER 2      MARKER 3
      SAMPLE 1, NA, 126.95, 160, 159.72, 162, 162.01, LENGTH, PEAK, LENGTH, PEAK
      SAMPLE 2, 152, 151.4, NA, NA, NA, NA,           LENGTH, PEAK, LENGTH, PEAK

如果格式看起来有点乱,希望这可能会有所帮助:在每一行中,应该有 141 列;第一列应该包含样本名称,然后是每个标记的 5 个等位基因的等位基因长度和峰值大小。例如,样品、标记 1 长度 1、标记 1 峰值 1、标记 1 长度 2、标记 1 峰值 2、标记 2 长度 1、标记 2 峰值 2 等。 这有点违反直觉,但想象一下每个标记都有列标题,然后是每个等位基因的大小和峰的子列。

我尝试过使用 dpylr、tidy data、melt、cast、dcast、reshape、reshape2、transpose ......但我对 R 不是很好,也没有运气。在实践中,使用长度和峰值作为子列可能不是很好/整洁的数据,但这是我的老板要求解释数据的。任何反馈表示赞赏!

谢谢!

编辑: 我按照建议运行了以下代码:

ultra_wide <-
  wide %>%
  group_by(SAMPLE, MARKER) %>%
  gather(key = "VARS", value = "VALS", c(LENGTH, PEAK)) %>%
  spread(MARKER, VALS) %>%
  summarize(MARKER1 = paste(c(B100), collapse = ", "), 
            MARKER2 = paste(c(B132), collapse = ", "),
            MARKER3 = paste(c(BL13), collapse = ", "),
            MARKER4 = paste(c(BT06), collapse = ", "),
            MARKER5 = paste(c(BT09), collapse = ", "),
            MARKER6 = paste(c(BT30), collapse = ", "),
            MARKER7 = paste(c(BTMS0044), collapse = ", "),
            MARKER8 = paste(c(BTMS0067), collapse = ", "),
            MARKER9 = paste(c(BTMS0106), collapse = ", "),
            MARKER10 = paste(c(B116), collapse = ", "),
            MARKER11 = paste(c(B118), collapse = ", "),
            MARKER12 = paste(c(B119), collapse = ", "),
            MARKER13 = paste(c(BT20), collapse = ", "),
            MARKER14 = paste(c(BTMS0114), collapse = ", "))

但是,该命令没有执行任何操作,因为发生了以下错误:

错误:行 (76, 77, 78, 79, 80), (30671, 30672, 30673, 30674, 30675), (81, 82, 83, 84, 85), (30676, 30677, 30678、30679、30680)

之后又持续了几行。

【问题讨论】:

  • 您的意思是 LENGTH、PEAK 的值,对吧?
  • 是的,对不起,让我编辑一下。
  • MARKER2、MARKER3 的编辑预期输出没有意义
  • 让我明白。你想通过标记转座等位基因,对吗?你能给我们一个简单的输出例子吗? Seams RNA-Seq 数据,您要按标记、等位基因还是两者都处理?
  • 这是 MicroSat 数据。对于每个标记,我想要所有 5 个彼此相邻的等位基因的等位基因长度和峰值大小。然后,下一个标记的数据应该在右侧,而不是在下方。那有意义吗?因此,对于每个标记,总共 10 列。每行应有 141 列 - 样本 ID,后跟上述数据。

标签: r dataframe data-structures dplyr reshape


【解决方案1】:

数据输入

首先,请提交重新创建数据框的代码,以便下一个人可以轻松地复制并粘贴代码并亲自查看数据框。在这里,我只是尝试根据您的规范重新创建数据框,特别是您提到每个标记有五个等位基因的部分。

# Vectors for dataframe

library(tidyverse)

SAMPLE <- c(rep("BRIS01", 5), rep("BRIS02", 5))
MARKER <- c(rep("B100", 5), rep("B200", 5))
ALLELE <- rep(paste("allele",1:5), times = 2)
LENGTH <- c(NA, 160, 162, 152, NA, NA, 160:163)
PEAK <- c(126.95,   159.72, 162.01, 151.4,  NA, NA, 150:153)

marker_data <- data.frame(SAMPLE, MARKER, ALLELE, LENGTH, PEAK, stringsAsFactors = FALSE)

marker_data
#>    SAMPLE MARKER   ALLELE LENGTH   PEAK
#> 1  BRIS01   B100 allele 1     NA 126.95
#> 2  BRIS01   B100 allele 2    160 159.72
#> 3  BRIS01   B100 allele 3    162 162.01
#> 4  BRIS01   B100 allele 4    152 151.40
#> 5  BRIS01   B100 allele 5     NA     NA
#> 6  BRIS02   B200 allele 1     NA     NA
#> 7  BRIS02   B200 allele 2    160 150.00
#> 8  BRIS02   B200 allele 3    161 151.00
#> 9  BRIS02   B200 allele 4    162 152.00
#> 10 BRIS02   B200 allele 5    163 153.00

请注意,在data.frame 中,我传递了stringsAsFactors = FALSE 选项,因为处理因子变量往往非常棘手

“传播”您的数据

至于您的输出,我将您以表格形式显示的内容作为您想要的结果输出。如果没有更多数据,很难获得每行所需的 141 列。获得答案的关键是在“收集”(或更常用的“熔化”)具有“值”的列之后“传播”MARKER 列,即LENGTHPEAK 列。传播前;但是,您应该创建一个具有唯一值的列,以防传播遇到相同的行。最后,您必须汇总以获取每个样本的一行,尽管您希望循环遍历 MARKER1-MARKER14 列以获得更优化/高效的代码。无论如何,我希望这会有所帮助。

marker_m <- 
  marker_data %>% 
  group_by(SAMPLE, MARKER) %>%
  gather(VARS, VALS, c(LENGTH, PEAK)) %>%
  mutate(i = row_number()) %>%
  spread(MARKER, VALS) %>% 
  summarize(MARKER1 = paste(c(B100), collapse = ", "), MARKER2 = paste(c(B200), collapse = ", "))

marker_m
#> # A tibble: 2 x 3
#>   SAMPLE MARKER1                                                  MARKER2 
#>   <chr>  <chr>                                                    <chr>   
#> 1 BRIS01 NA, 126.95, 160, 159.72, 162, 162.01, 152, 151.4, NA, NA NA, NA,~
#> 2 BRIS02 NA, NA, NA, NA, NA, NA, NA, NA, NA, NA                   NA, NA,~

【讨论】:

  • 遗憾的是没有生成数据框的代码,它只是被一个excel文件读入。它看起来与您生成的 marker_data 非常相似,除了在每个样本中检测到 14 个标记(每个样本中的标记相同,而不是标记 1 -> 样本 1、标记 2 -> 样本 2)。感谢您对数据传播的帮助,我会看看我能做些什么。
  • 我明白你为什么会遇到这个问题。我建议您阅读以下回复:stackoverflow.com/a/45898919/5425826。简而言之,您的数据无法传播,因为 MARKER 列无法“唯一”识别行,这就是您看到“行的重复标识符”错误消息的原因。你能用 dput(wide) 的结果发布你的问题吗?
  • 控制台中 dput(wide) 的输出因太大而被截断,但最后几行显示为:“299.66”、“299.82”、“301.52”、“302.36”、“302.37” ", "302.38", "302.4", "304.88"), class= "factor")), row.names = c(NA, 30595L), class= "data.frame") 当我用视图打开数据框时() 它只是向我展示了与宽相同的表。
  • 好的。好吧,我将修改我的回复并在传播之前包含mutate(i = row_number()),以确保我们有唯一的行。但是如果您不发布可重现的示例,其他人很难知道会发生什么。
猜你喜欢
  • 2023-01-31
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-26
  • 1970-01-01
相关资源
最近更新 更多