我可以根据列的标识来分隔列吗?
Can I separate a column based on its identity?
我是 R 的新手,我想知道是否可以根据列的标识来分隔列?例如,我想将第 5 列分成新列,其中一列中所有以 "E-" 开头的列,另一列中所有以 "D-" 开头的列。
chr1 11046 12418 2 E-H3K27ac,D-Both
chr1 18615 19392 2 D-Both,E-Both
chr1 27209 28559 3 E-H3K4me1,D-Both,E-Both
chr1 35274 35492 1 E-H3K4me1
chr1 36589 38097 2 D-Both,E-Both
chr1 43655 45148 2 D-Both,E-Both
chr1 49265 50054 2 D-Both,E-H3K4me1
chr1 50117 50465 1 E-H3K4me1
所以它看起来像:
chr1 11046 12418 2 E-H3K27ac D-Both
chr1 18615 19392 2 E-Both D-Both
chr1 27209 28559 3 E-H3K4me1,E-Both D-Both
chr1 35274 35492 1 E-H3K4me1
chr1 36589 38097 2 E-Both D-Both
chr1 43655 45148 2 E-Both D-Both
chr1 49265 50054 2 E-H3K4me1 D-Both
chr1 50117 50465 1 E-H3K4me1
我不确定是否需要先处理包含 3 个条目的行。 (在这个例子中,我可能只是将第 3 行中的 2 个 E- 开始转换为 E-Both)。抱歉,如果已经有人问过类似的问题。我仍在学习行话,所以我对 r 问题的搜索技巧有限。
我们可以用 base R
来做到这一点。用strsplit
分隔符,
拆分'Col'(如果是factor
class,用as.character(df1$Col)
包起来)成list
,然后paste
按第一个字符(substr(x, 1, 1)
)分组后的元素,sort
按降序排列。我们用 NA 填充 list
中只有一个元素的元素,rbind
list
元素并创建两个新列 'E_col' 和 'D_col'
lst <- lapply(strsplit(df1$Col, ","), function(x)
sort(tapply(x, substr(x, 1, 1), FUN = toString), decreasing=TRUE))
df1[c("E_col", "D_col")] <- do.call(rbind, lapply(lst, `length<-`, max(lengths(lst))))
df1
# chr ID1 ID2 val Col E_col D_col
#1 chr1 11046 12418 2 E-H3K27ac,D-Both E-H3K27ac D-Both
#2 chr1 18615 19392 2 D-Both,E-Both E-Both D-Both
#3 chr1 27209 28559 3 E-H3K4me1,D-Both,E-Both E-H3K4me1, E-Both D-Both
#4 chr1 35274 35492 1 E-H3K4me1 E-H3K4me1 <NA>
#5 chr1 36589 38097 2 D-Both,E-Both E-Both D-Both
#6 chr1 43655 45148 2 D-Both,E-Both E-Both D-Both
#7 chr1 49265 50054 2 D-Both,E-H3K4me1 E-H3K4me1 D-Both
#8 chr1 50117 50465 1 E-H3K4me1 E-H3K4me1 <NA>
或者另一种选择是使用 splitstackshape
中的 cSplit
拆分 'Col' 并将数据集重塑为 'long' 格式,然后使用 dcast
我们将其更改为 'wide'
library(splitstackshape)
dcast(cSplit(df1, "Col", ",", "long")[, toString(Col) ,
.(chr, ID1, ID2, val, grp=factor(substr(Col, 1, 1), levels = c("E", "D")))],
... ~ grp, value.var = "V1")
注意:正如@Frank 在评论中建议的那样,最好将其保留为 'long' 格式(cSplit(df1, "Col", ",", "long")
的输出)而不是将其组合回 'wide'格式
数据
df1 <- structure(list(chr = c("chr1", "chr1", "chr1", "chr1", "chr1",
"chr1", "chr1", "chr1"), ID1 = c(11046L, 18615L, 27209L, 35274L,
36589L, 43655L, 49265L, 50117L), ID2 = c(12418L, 19392L, 28559L,
35492L, 38097L, 45148L, 50054L, 50465L), val = c(2L, 2L, 3L,
1L, 2L, 2L, 2L, 1L), Col = c("E-H3K27ac,D-Both", "D-Both,E-Both",
"E-H3K4me1,D-Both,E-Both", "E-H3K4me1", "D-Both,E-Both", "D-Both,E-Both",
"D-Both,E-H3K4me1", "E-H3K4me1")), .Names = c("chr", "ID1", "ID2",
"val", "Col"), class = "data.frame", row.names = c(NA, -8L))
我是 R 的新手,我想知道是否可以根据列的标识来分隔列?例如,我想将第 5 列分成新列,其中一列中所有以 "E-" 开头的列,另一列中所有以 "D-" 开头的列。
chr1 11046 12418 2 E-H3K27ac,D-Both
chr1 18615 19392 2 D-Both,E-Both
chr1 27209 28559 3 E-H3K4me1,D-Both,E-Both
chr1 35274 35492 1 E-H3K4me1
chr1 36589 38097 2 D-Both,E-Both
chr1 43655 45148 2 D-Both,E-Both
chr1 49265 50054 2 D-Both,E-H3K4me1
chr1 50117 50465 1 E-H3K4me1
所以它看起来像:
chr1 11046 12418 2 E-H3K27ac D-Both
chr1 18615 19392 2 E-Both D-Both
chr1 27209 28559 3 E-H3K4me1,E-Both D-Both
chr1 35274 35492 1 E-H3K4me1
chr1 36589 38097 2 E-Both D-Both
chr1 43655 45148 2 E-Both D-Both
chr1 49265 50054 2 E-H3K4me1 D-Both
chr1 50117 50465 1 E-H3K4me1
我不确定是否需要先处理包含 3 个条目的行。 (在这个例子中,我可能只是将第 3 行中的 2 个 E- 开始转换为 E-Both)。抱歉,如果已经有人问过类似的问题。我仍在学习行话,所以我对 r 问题的搜索技巧有限。
我们可以用 base R
来做到这一点。用strsplit
分隔符,
拆分'Col'(如果是factor
class,用as.character(df1$Col)
包起来)成list
,然后paste
按第一个字符(substr(x, 1, 1)
)分组后的元素,sort
按降序排列。我们用 NA 填充 list
中只有一个元素的元素,rbind
list
元素并创建两个新列 'E_col' 和 'D_col'
lst <- lapply(strsplit(df1$Col, ","), function(x)
sort(tapply(x, substr(x, 1, 1), FUN = toString), decreasing=TRUE))
df1[c("E_col", "D_col")] <- do.call(rbind, lapply(lst, `length<-`, max(lengths(lst))))
df1
# chr ID1 ID2 val Col E_col D_col
#1 chr1 11046 12418 2 E-H3K27ac,D-Both E-H3K27ac D-Both
#2 chr1 18615 19392 2 D-Both,E-Both E-Both D-Both
#3 chr1 27209 28559 3 E-H3K4me1,D-Both,E-Both E-H3K4me1, E-Both D-Both
#4 chr1 35274 35492 1 E-H3K4me1 E-H3K4me1 <NA>
#5 chr1 36589 38097 2 D-Both,E-Both E-Both D-Both
#6 chr1 43655 45148 2 D-Both,E-Both E-Both D-Both
#7 chr1 49265 50054 2 D-Both,E-H3K4me1 E-H3K4me1 D-Both
#8 chr1 50117 50465 1 E-H3K4me1 E-H3K4me1 <NA>
或者另一种选择是使用 splitstackshape
中的 cSplit
拆分 'Col' 并将数据集重塑为 'long' 格式,然后使用 dcast
我们将其更改为 'wide'
library(splitstackshape)
dcast(cSplit(df1, "Col", ",", "long")[, toString(Col) ,
.(chr, ID1, ID2, val, grp=factor(substr(Col, 1, 1), levels = c("E", "D")))],
... ~ grp, value.var = "V1")
注意:正如@Frank 在评论中建议的那样,最好将其保留为 'long' 格式(cSplit(df1, "Col", ",", "long")
的输出)而不是将其组合回 'wide'格式
数据
df1 <- structure(list(chr = c("chr1", "chr1", "chr1", "chr1", "chr1",
"chr1", "chr1", "chr1"), ID1 = c(11046L, 18615L, 27209L, 35274L,
36589L, 43655L, 49265L, 50117L), ID2 = c(12418L, 19392L, 28559L,
35492L, 38097L, 45148L, 50054L, 50465L), val = c(2L, 2L, 3L,
1L, 2L, 2L, 2L, 1L), Col = c("E-H3K27ac,D-Both", "D-Both,E-Both",
"E-H3K4me1,D-Both,E-Both", "E-H3K4me1", "D-Both,E-Both", "D-Both,E-Both",
"D-Both,E-H3K4me1", "E-H3K4me1")), .Names = c("chr", "ID1", "ID2",
"val", "Col"), class = "data.frame", row.names = c(NA, -8L))