如何在 r 的新列中拆分逗号
Posted
技术标签:
【中文标题】如何在 r 的新列中拆分逗号【英文标题】:How Can I split a comma in new column in r 【发布时间】:2014-03-30 18:08:09 【问题描述】:我有这个数据
CHOM POS REF ALT
1 121 A AA,AT
2 254 GCGC GCGCG,AGCG
3 214 C T
我需要将 ALT 列拆分为
CHOM POS REF ALT ALT1 ALT2 ...
1 121 A AA AT 0
2 254 GCGC GCGCG AGCG 0
3 214 C T 0 0
我试过了,但错误是
alt=x$ALT
strsplit(alt, ",")
注意: ALT 和 REF 有很多种,按逗号表示的最大值为 4。 如果有逗号,只需输入值 0 或 NA
【问题讨论】:
不,有时我在 alt colmun 中有这样的 AAT,CG,AA 所以我需要将每个逗号拆分到一个新列中 五万,很大 【参考方案1】:新答案
我会编写如下函数来拆分列:
splitFun <- function(inVec, sep = ",", newName = "ALT", fill = NA)
if (!is.character(inVec)) inVec <- as.character(inVec)
X <- strsplit(inVec, sep, fixed = TRUE)
cols <- vapply(X, length, 1L)
M <- matrix(
fill, nrow = length(inVec), ncol = max(cols),
dimnames = list(NULL, make.unique(rep(newName, max(cols)), sep="")))
M[cbind(rep(sequence(length(X)), cols), sequence(cols))] <-
unlist(X, use.names=FALSE)
M
用法很简单:
splitFun(mydf$ALT) ## Modify default arguments accordingly
# ALT ALT1 ALT2
# [1,] "AA" "AT" NA
# [2,] "GCGCG" "AGCG" NA
# [3,] "GCGCG" "AT" "AA"
cbind(mydf, splitFun(mydf$ALT))
# CHOM POS REF ALT ALT ALT1 ALT2
# 1 1 121 A AA,AT AA AT <NA>
# 2 2 254 GCGC GCGCG,AGCG GCGCG AGCG <NA>
# 3 1 123 GCGC GCGCG,AT,AA GCGCG AT AA
时间应该是相当有效的。这是与“splitstackshape”方法(也可以处理不平衡情况)的比较。
system.time(splitstackshape:::read.concat(
bigDf$ALT, sep=",", col.prefix="ALT"))
# user system elapsed
# 1.197 0.000 1.202
system.time(splitFun(bigDf$ALT))
# user system elapsed
# 0.069 0.000 0.068
对于上述情况,使用的样本数据为:
mydf <- data.frame(CHOM = c(1, 2, 1), POS = c(121, 254, 123),
REF = c("A", "GCGC", "GCGC"),
ALT = c("AA,AT", "GCGCG,AGCG", "GCGCG,AT,AA"))
mydf
# CHOM POS REF ALT
# 1 1 121 A AA,AT
# 2 2 254 GCGC GCGCG,AGCG
# 3 1 123 GCGC GCGCG,AT,AA
bigDf <- do.call(rbind, replicate(10000, mydf, simplify = FALSE))
旧答案
你可以试试我的“splitstackshape”包中的concat.split
:
library(splitstackshape)
concat.split(mydf, "ALT", ",") ## Add `drop = TRUE` to drop the original column
# CHOM POS REF ALT ALT_1 ALT_2
# 1 1 121 A AA,AT AA AT
# 2 2 254 GCGC GCGCG,AGCG GCGCG AGCG
还有来自“reshape2”包的colsplit
:
library(reshape2)
colsplit(as.character(mydf$ALT), ",", c("ALT", "ALT1"))
# ALT ALT1
# 1 AA AT
# 2 GCGCG AGCG
您可以使用cbind
将输出添加到您的原始数据集中。
【讨论】:
我不知道splitstackshape
,非常好的功能:concat.split
当然是+1!
可以用...,colClasses="character")
提高它的速度吗?这是提高read.table
效率的标准建议的一部分。
@IShouldBuyABoat,这个功能的灵感来源于你 (see here)。如果得到的拆分是平衡的,我有a variation of the function 使用fread
,它快得多。当拆分可能不平衡时,此函数使用fill = TRUE
,它使用count.fields
检查前6 行之后是否有比前几行更多的字段。 count.fields
可能会被替换为 grep
以获得更快的速度。
如果有任何信用到期,它可能应该扩展到@GaborGrothendieck。我很确定我从他的 Rhelp 帖子中学到了这个技巧。
有些可能还有逗号,要明确我是否需要逗号,但如果不只是放 0 或 NA,则在新列中。【参考方案2】:
考虑你的数据是dat
> dat2 <- data.frame(dat[, -4], sapply(strsplit(levels(dat$ALT), ","), cbind))
> colnames(dat2)[4:5] <- c("ALT", "ALT1")
> dat2
CHOM POS REF ALT ALT1
1 1 121 A AA GCGCG
2 2 254 GCGC AT AGCG
【讨论】:
我认为只是偶然的成功。除非您使用levels(dat$ALT)[dat$ALT]
,否则当某些级别在不规则位置重复时,这将失败。考虑改用as.character(dat$ALT)
dat2
【参考方案3】:
> dat[ c("ALT", "ALT1")] <- read.table(text=as.character(dat$ALT), sep=",")
> dat
CHOM POS REF ALT ALT1
1 1 121 A AA AT
2 2 254 GCGC GCGCG AGCG
【讨论】:
+1。这几乎是激发我的concat.split
函数开始的原因:-)
是的。它可能是重复的,但 SO 不会奖励识别或确认重复,所以我在搜索和发布答案之间交替。我只是进行了搜索,并没有立即找到我要查找的内容,但这个问题肯定有很多有趣的变化。
也许它会起作用,但我可以在有逗号的时候分割吗?像这样
AA,T,G row2 是 A T 。它将是 AA T G 然后是 A T NA以上是关于如何在 r 的新列中拆分逗号的主要内容,如果未能解决你的问题,请参考以下文章
如何检查一系列字符串是不是包含在 PANDAS DataFrame 列中并将该字符串分配为行中的新列?