如何在 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 列中并将该字符串分配为行中的新列?

如何将文件路径及其名称插入 SSIS 的新列中?

如何有条件地将子字符串复制到熊猫数据框的新列中?

如何根据oracle plsql中列中的逗号分隔值拆分选择查询行

如何访问 pandas 数据框列中的字典元素并对其进行迭代以创建填充有各自值的新列?