我有一个名为SNP的数据帧,有6000列和500行。数据帧如下表所示:
|sample | SNP1 | SNP2 | SNP3 |
|:--------------|---------:|---------:|---------:|
|s1 | AA | TT | GG |
|s2 | CC | AT | AA |
|s3 | AT | CC | AA |
我必须重新排列分析格式。我想做的是对于每个 SNP 列中的每个字符(例如,我的意思是第二列的"AA"、"CC"、"AT",SNP1(,我想为每个样本制作 2 个连续的行,然后想拆分字符并将它们分配到新创建的两行样本中。 为了您的方便,我想制作下表格式:
|sample | SNP1 | SNP2 | SNP3 |
|:--------------|---------:|---------:|---------:|
|s1 | A | T | G |
|s1 | A | T | G |
|s2 | C | A | A |
|s2 | C | T | A |
|s3 | A | C | A |
|s3 | T | C | A |
如果有人能帮助我解决,将不胜感激。
注意:我添加了datafram的屏幕截图,以防我添加的格式被替换,我是新来的。
以下是使用tidyverse
包和正则表达式的一种可能的解决方案:
library(tidyverse)
snp <- data.frame(sample = c("s1", "s2", "s3"),
SNP1 = c("AA", "CC", "AT"),
SNP2 = c("TT", "AT", "CC"),
SNP3 = c("GG", "AA", "AA"))
snp %>% mutate_at(-1, ~str_extract(.x, "^.")) %>%
bind_rows(mutate_at(snp, -1, ~str_extract(.x, ".$"))) %>%
arrange(sample)
sample SNP1 SNP2 SNP3
1 s1 A T G
2 s1 A T G
3 s2 C A A
4 s2 C T A
5 s3 A C A
6 s3 T C A
简短解释:首先我提取除第一列以外的所有列的第一个字母(^.
(,因此-1
(。 然后我提取除第一列以外的所有列的最后一个字母(.$
(。最后,我将这两个数据帧粘贴在一起,并使用arrange
重新排列结果。
这是一个data.table
解决方案。
您可能会发现这篇文章很有启发性。 堆栈溢出示例说明 tstrsplit
require(data.table)
df = data.table(sample=c("s1","s2","s3"),
SNP1=c("AA","CC","AT"),
SNP2=c("TT","AT","CC"),
SNP3=c("GG","AA","AA"))
# get the names of the relevant columns
x=grep("SNP",names(df),value = TRUE)
# split each column. The 'by' functionality will
# manage the stacking of the results.
df[,lapply(.SD,tstrsplit,'',fixed=TRUE),.SDcols=x,by=sample]
输出:
|sample |SNP1 |SNP2 |SNP3 |
|:------|:----|:----|:----|
|s1 |A |T |G |
|s1 |A |T |G |
|s2 |C |A |A |
|s2 |C |T |A |
|s3 |A |C |A |
|s3 |T |C |A |
如果字符串是固定长度但不一定是长度 2,这似乎仍然有效。 我没有在空字符串上对此进行测试。警告 emptor