r语言 - 我如何将2列(X, Y),管道分隔表转换为X by Y数据帧或长格式?



我花了一个小时的时间试图将两列格式重新格式化成更有用的格式。

我有以下输入(一个2列数据帧/标题):

输入
TGGGAAGGTTATGTGC-1  CMO305|CMO306|CMO312    3698|3806|12182
TGTTCTACATGACAGG-1  CMO305|CMO306|CMO312    3027|1449|4184
ACTGATGCAGAGTGAC-1  CMO305|CMO307   6802|4715
ATCGTCCGTTACCCAA-1  CMO305|CMO307   5599|7019
ATGCATGTCATGACAC-1  CMO305|CMO307   10872|16729
GTGAGTTAGTCCGCCA-1  CMO305|CMO307   10096|3434

期望输出(A - wide)

<表类>CMO305CMO306CMO307CMO312tbody><<tr>TGGGAAGGTTATGTGC-136983806012182TGTTCTACATGACAGG-13027144904184ACTGATGCAGAGTGAC-16802047150ATCGTCCGTTACCCAA-15599070190ATGCATGTCATGACAC-1108720167290GTGAGTTAGTCCGCCA-110096034340

假设列名为'col1', 'col2', 'col3',在col2和col3上使用separate_rows,将sep用作|(regex模式是默认的-因此转义元字符|以从字面上读取它),然后用pivot_widertidyr重塑为'wide'

library(dplyr)
library(tidyr)
long_df <- df1 %>%
mutate(rn = row_number()) %>% 
separate_rows(c(col2, col3), sep = "\|", convert = TRUE)

与产出

long_df %>%
select(col2, col3)
# A tibble: 14 × 2
col2    col3
<chr>  <int>
1 CMO305  3698
2 CMO306  3806
3 CMO312 12182
4 CMO305  3027
5 CMO306  1449
6 CMO312  4184
7 CMO305  6802
8 CMO307  4715
9 CMO305  5599
10 CMO307  7019
11 CMO305 10872
12 CMO307 16729
13 CMO305 10096
14 CMO307  3434

或者如果我们需要宽幅格式

wide_df <- long_df %>% 
pivot_wider(names_from = col2, values_from = col3, values_fill = 0) %>%
select(-rn)

与产出

wide_df
# A tibble: 6 × 5
col1               CMO305 CMO306 CMO312 CMO307
<chr>               <int>  <int>  <int>  <int>
1 TGGGAAGGTTATGTGC-1   3698   3806  12182      0
2 TGTTCTACATGACAGG-1   3027   1449   4184      0
3 ACTGATGCAGAGTGAC-1   6802      0      0   4715
4 ATCGTCCGTTACCCAA-1   5599      0      0   7019
5 ATGCATGTCATGACAC-1  10872      0      0  16729
6 GTGAGTTAGTCCGCCA-1  10096      0      0   3434

数据
df1 <- structure(list(col1 = c("TGGGAAGGTTATGTGC-1", "TGTTCTACATGACAGG-1", 
"ACTGATGCAGAGTGAC-1", "ATCGTCCGTTACCCAA-1", "ATGCATGTCATGACAC-1", 
"GTGAGTTAGTCCGCCA-1"), col2 = c("CMO305|CMO306|CMO312", "CMO305|CMO306|CMO312", 
"CMO305|CMO307", "CMO305|CMO307", "CMO305|CMO307", "CMO305|CMO307"
), col3 = c("3698|3806|12182", "3027|1449|4184", "6802|4715", 
"5599|7019", "10872|16729", "10096|3434")), 
class = "data.frame", row.names = c(NA, 
-6L))

我们可以使用cSplit函数从splitstackshake包分离行,然后使用pivot_wider作为akrun在他的回答:

library(splitstackshape)
library(dplyr)
library(tidyr)
df <- cSplit(df1, c("col2", "col3"), "|", direction = "long")
# output 1
df %>% 
as_tibble() %>% 
select(2,3)
# output 2
df %>% 
pivot_wider(
names_from = col2,
values_from = col3,
values_fill = 0
)

output1:

col2    col3
<chr>  <int>
1 CMO305  3698
2 CMO306  3806
3 CMO312 12182
4 CMO305  3027
5 CMO306  1449
6 CMO312  4184
7 CMO305  6802
8 CMO307  4715
9 CMO305  5599
10 CMO307  7019
11 CMO305 10872
12 CMO307 16729
13 CMO305 10096
14 CMO307  3434

output2:

# A tibble: 6 × 5
col1               CMO305 CMO306 CMO312 CMO307
<chr>               <int>  <int>  <int>  <int>
1 TGGGAAGGTTATGTGC-1   3698   3806  12182      0
2 TGTTCTACATGACAGG-1   3027   1449   4184      0
3 ACTGATGCAGAGTGAC-1   6802      0      0   4715
4 ATCGTCCGTTACCCAA-1   5599      0      0   7019
5 ATGCATGTCATGACAC-1  10872      0      0  16729
6 GTGAGTTAGTCCGCCA-1  10096      0      0   3434

最新更新