R:如何将每5行的选择转换为单行?

时间:2019-04-17 14:42:01

标签: r dataframe data-structures dplyr reshape

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

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,整洁的数据,融化,投射,dcast,重塑,reshape2,转置...但是我对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)

此后又持续了几行。

1 个答案:

答案 0 :(得分:0)

数据输入

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

# 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和{“聚集”(或更通常称为“融化”)之后“传播” LENGTH列{1}}列。散布前;但是,您应该创建一个具有唯一值的列,以防扩展遇到相同的行。最后,您必须总结一下,以便为每个样本获得一行,尽管您希望遍历MARKER1-MARKER14列以获得更优化/更有效的代码。无论如何,我希望这会有所帮助。

PEAK