【问题标题】:R data processing involving strsplit涉及 strsplit 的 R 数据处理
【发布时间】:2018-04-11 19:13:47
【问题描述】:

我有一个如下所示的数据框:

> df
                   V1         V2    V3 V4       V5                 V6 V7
1  chr1:859582-899582    AHR.pfm 33440  - 9.188581          gcacgcaac NA
2  chr2:859582-899582   AIRE.pfm  7387  + 7.982141 TCTGGTTCAGTTGGATGC NA
3  chr1:859582-899582 AIRE.3.pfm 30639  - 8.127811 aaaaccaaacaaacaaaa NA
4 chr13:859582-899582   ALX1.pfm 11835  + 7.485710       GTAATTGTGTTA NA
5 chr21:859582-899582 ALX1.1.pfm 16260  + 9.529333       GTAATTAATTTA NA
6  chrX:859582-899582 ALX1.2.pfm 20686  + 9.241755       CTAATTAATTTA NA

我想将多个新列附加到此数据框中,并且所有这些列都将包含此数据框中的信息。详情如下:

  1. 附加列 chr 具有值 strsplit(df$V1,":")[[1]] (split : 上的第一列值并将第一个索引分配给这个新的 列)
  2. 附加列 start 具有值 strsplit(df$V1,":")[[2]] => strsplit(df$V1,"-")[[1]] (首先拆分第一列值:取 第二个索引,然后将其拆分 - 并将第一个索引分配给这个新的 列)
  3. 附加列 end 具有值 df$start + length(df$V6)(添加 start 的值,V6 列的字符长度)
  4. 附加列 TF 具有值 strsplit(df$V2,".")[[1]] (split 上的第二列值。并将第一个索引分配给这个新的 列

所以附加的新列看起来像:

chr1 859582 859591  AHR
chr2 859582 859600  AIRE
chr1 859582 859600  AIRE
chr13 859582 859594 ALX1
chr21 859582 859594 ALX1
chrX 859582 859594  ALX1

【问题讨论】:

    标签: r dataframe strsplit


    【解决方案1】:

    1) tidyr/dplyr 这会将V1 列分隔为chrstartend 列,然后附加一个TF 列,其中包含@ 中第一个点之前的所有内容987654327@。 mutate 的替代品可能是 separate(V2, "TF", extra = "drop"),它会删除 V2 并将 TF 放在它的位置。如果您还想保留原始列,请添加 separate 参数 remove=FALSE

    library(dplyr)
    library(tidyr)
    
    library(dplyr)
    library(tidyr)
    df %>% 
       separate(V1, c("chr", "start", "end"), convert = TRUE) %>%
       mutate(TF = sub("[.].*", "", V2), end = end + nchar(V6))
    

    给予:

        chr  start    end         V2    V3 V4       V5                 V6 V7   TF
    1  chr1 859582 899591    AHR.pfm 33440  - 9.188581          gcacgcaac NA  AHR
    2  chr2 859582 899600   AIRE.pfm  7387  + 7.982141 TCTGGTTCAGTTGGATGC NA AIRE
    3  chr1 859582 899600 AIRE.3.pfm 30639  - 8.127811 aaaaccaaacaaacaaaa NA AIRE
    4 chr13 859582 899594   ALX1.pfm 11835  + 7.485710       GTAATTGTGTTA NA ALX1
    5 chr21 859582 899594 ALX1.1.pfm 16260  + 9.529333       GTAATTAATTTA NA ALX1
    6  chrX 859582 899594 ALX1.2.pfm 20686  + 9.241755       CTAATTAATTTA NA ALX1
    

    2) 没有包 仅使用基本 R 的一种方法是:

    nms <- c("chr", "start", "end")
    df2 <- cbind(df[-1], 
     read.table(text = sub("-", ":", df$V1), sep = ":", as.is = TRUE, col.names = nms), 
     TF = sub("[.].*", "", df$V2), 
     stringsAsFactors = FALSE)
     df2 <- transform(df2, end = end + nchar(V6))
    

    给予:

    > df2
              V2    V3 V4       V5                 V6 V7   chr  start    end   TF
    1    AHR.pfm 33440  - 9.188581          gcacgcaac NA  chr1 859582 899591  AHR
    2   AIRE.pfm  7387  + 7.982141 TCTGGTTCAGTTGGATGC NA  chr2 859582 899600 AIRE
    3 AIRE.3.pfm 30639  - 8.127811 aaaaccaaacaaacaaaa NA  chr1 859582 899600 AIRE
    4   ALX1.pfm 11835  + 7.485710       GTAATTGTGTTA NA chr13 859582 899594 ALX1
    5 ALX1.1.pfm 16260  + 9.529333       GTAATTAATTTA NA chr21 859582 899594 ALX1
    6 ALX1.2.pfm 20686  + 9.241755       CTAATTAATTTA NA  chrX 859582 899594 ALX1
    

    注意:df 以可重现的形式:

    Lines <- "
                       V1         V2    V3 V4       V5                 V6 V7
    1  chr1:859582-899582    AHR.pfm 33440  - 9.188581          gcacgcaac NA
    2  chr2:859582-899582   AIRE.pfm  7387  + 7.982141 TCTGGTTCAGTTGGATGC NA
    3  chr1:859582-899582 AIRE.3.pfm 30639  - 8.127811 aaaaccaaacaaacaaaa NA
    4 chr13:859582-899582   ALX1.pfm 11835  + 7.485710       GTAATTGTGTTA NA
    5 chr21:859582-899582 ALX1.1.pfm 16260  + 9.529333       GTAATTAATTTA NA
    6  chrX:859582-899582 ALX1.2.pfm 20686  + 9.241755       CTAATTAATTTA NA"
    df <- read.table(text = Lines, as.is = TRUE)
    

    【讨论】:

    • @g-grothendieck 非常感谢您提供的多种解决方案。这个解决方案只有一个问题,那就是end 列。 end 列应包含 start + length of characters in df$V6 的值。例如,对于第一行,它将是 859582 + 9 = 859591 而不是 `899582?这就是我现在得到的。你能指导我怎么做吗?再次感谢
    • 好的。已添加。
    • @g-grothedieck 你能帮我解决这个question 用foreach 循环或parSapply 替换for 循环吗?谢谢。
    【解决方案2】:

    您可以编写一个函数 fun 来执行此操作,并重复调用 sapply/strsplit

    fun <- function(DF){
        chr <- sapply(strsplit(DF[[1]], ":"), `[`, 1)
        start <- sapply(strsplit(DF[[1]], ":"), `[`, 2)
        end <- as.integer(sapply(strsplit(start, "-"), `[`, 1)) + nchar(DF[[6]])
        start <- sapply(strsplit(start, "-"), `[`, 1)
        TF <- sapply(strsplit(DF[[2]], "\\."), `[`, 1)
        cbind(DF, data.frame(chr, start, end, TF))
    }
    
    fun(df)
    

    请注意,必须使用类characterV1V2 两列读取数据,而不是factor。如果它们属于factor 类,则首先将它们强制为character,或者,如果适用,设置参数stringsAsFactors = FALSE

    数据。

    df <-
    structure(list(V1 = c("chr1:859582-899582", "chr2:859582-899582", 
    "chr1:859582-899582", "chr13:859582-899582", "chr21:859582-899582", 
    "chrX:859582-899582"), V2 = c("AHR.pfm", "AIRE.pfm", "AIRE.3.pfm", 
    "ALX1.pfm", "ALX1.1.pfm", "ALX1.2.pfm"), V3 = c(33440L, 7387L, 
    30639L, 11835L, 16260L, 20686L), V4 = c("-", "+", "-", "+", "+", 
    "+"), V5 = c(9.188581, 7.982141, 8.127811, 7.48571, 9.529333, 
    9.241755), V6 = c("gcacgcaac", "TCTGGTTCAGTTGGATGC", "aaaaccaaacaaacaaaa", 
    "GTAATTGTGTTA", "GTAATTAATTTA", "CTAATTAATTTA"), V7 = c(NA, NA, 
    NA, NA, NA, NA)), .Names = c("V1", "V2", "V3", "V4", "V5", "V6", 
    "V7"), class = "data.frame", row.names = c("1", "2", "3", "4", 
    "5", "6"))
    

    【讨论】:

    • @rui-barradad 非常感谢您的解决方案。这个解决方案只有一个问题,那就是end 列。 end 列应包含 start + length of characters in df$V6 的值。例如,对于第一行,它将是 859582 + 9 = 859591 而不是 `899582?这就是我现在得到的。你能指导我怎么做吗?再次感谢。
    • end &lt;- as.numeric(sapply(strsplit(start, "-"), [, 1)) + nchar(df$V6) 这就是我在寻找end 列的内容。
    • @Newbie 刚刚使用该修改进行了编辑。看看是不是这个。
    • 对于结束列,您必须选择第一个索引(即开始列),然后在其中添加 nchar。它将是:end &lt;- as.numeric(sapply(strsplit(start, "-"), [, 1)) + nchar(DF[[6]]) 请注意,我选择了第一个索引。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多