簡體   English   中英

使用Strsplit和R連接拆分R中的大型數據文件

[英]Splitting a Large Data File in R using Strsplit and R Connection

您好我正在嘗試將大數據文件讀入R.它是一個制表符分隔文件,但前兩列填充了由“|”分隔的多個數據。 該文件看起來像:

A|1   B|2   0.5  0.4
C|3   D|4   0.9  1

我只關心第一列和第二列以及第三和第四列中的第一個值。 最后,我希望最終得到每個行的向量,如下所示:

A  B  0.5  0.4

我正在使用連接來讀取文件:

con <- file("inputfile.txt", open = "r")
lines <- readLines(con)

這給了我:

lines[1]
[1] "A|1\tB|2/t0.5\t0.4"

然后我使用strsplit分割制表符分隔文件:

linessplit <- strsplit(lines, split="\t")

這給了我:

linessplit[1]
[1] "A|1" "B|2" 
[3] "0.5" "0.4"

當我嘗試以下操作將“A | 1”拆分為“A”“1”時:

line1 <- linessplit[1]
l1 <- strsplit(line1[1], split = "|")

我明白了:

"Error in strsplit(line1[1], split = "|") : non-character argument"

有沒有人有辦法解決這個問題? 謝謝!

由於您提供了一種方法,我解釋了代碼中的錯誤,即使對於您的問題,也許您必須考慮另一種方法。 無論如何,拋開個人對代碼的品味,問題是:

  1. 你必須用雙括號line1[[1]]提取列表的第一個元素
  2. split參數接受正則表達式。 如果你提供| 這是一個元字符,它不會被理解為是 你必須用\\\\|來逃避它 或者(正如@nongkrong所建議的那樣)你必須使用fixed = T參數,它允許你完全按原樣匹配字符串(比方說,沒有它們作為元字符的含義)。

最終的代碼是l1 <- strsplit(line1[[1]], split = "\\\\|")

作為最后的個人考慮,您可以考慮一個lapply解決方案:

lapply(linessplit, strsplit, split = "|", fixed = T)

這是我對原始問題的解決方案

分裂線

"A|1\tB|2\t0.5\t0.4"
"C|3\tD|4\t0.9\t1"

A  B  0.5  0.4
C  D  0.9  1

以下是我的代碼:

lines <- c("A|1\tB|2\t0.5\t0.4", "C|3\tD|4\t0.9\t1", "E|5\tF|6\t0.7\t0.2")
lines

library(reshape2)
linessplit <- colsplit(lines, pattern="\t", names=c(1:4))
linessplit

split_n_select <- function(x, sel=c(1), pat="\\|", nam=c(1:2)){
  tmp <- t(colsplit(x, pattern=pat, names=nam))
  tmp[sel,]
}

linessplit2 <- sapply(linessplit, split_n_select)
linessplit2

這是打破它:

  1. 將原始數據讀入

     lines <- c("A|1\\tB|2\\t0.5\\t0.4", "C|3\\tD|4\\t0.9\\t1", "E|5\\tF|6\\t0.7\\t0.2") lines 

    結果:

      [1] "A|1\\tB|2\\t0.5\\t0.4" "C|3\\tD|4\\t0.9\\t1" "E|5\\tF|6\\t0.7\\t0.2" 
  2. 加載reshape2庫以導入函數colsplit ,然后使用模式“\\ t”將行拆分為4列,名為1,2,3,4。

     library(reshape2) linessplit <- colsplit(lines, pattern="\\t", names=c(1,2,3,4)) linessplit 

    結果:

      1 2 3 4 1 A|1 B|2 0.5 0.4 2 C|3 D|4 0.9 1.0 3 E|5 F|6 0.7 0.2 
  3. 這是一個函數來取一行,分成行並選擇我們想要的行。

    把第一排linessplit變成colsplit

     tmp <- colsplit(linessplit[1,], pattern="\\\\|", names=c(1:2)) tmp 

    結果:

      1 2 1 A 1 2 B 2 3 0.5 NA 4 0.4 NA 

    轉置

     tmp <- t(colsplit(linessplit[1,], pattern="\\\\|", names=c(1:2))) tmp 

    結果:

      [,1] [,2] [,3] [,4] 1 "A" "B" "0.5" "0.4" 2 " 1" " 2" NA NA 

    選擇第一行:

     tmp[1,] 

    結果:

     [1] "A" "B" "0.5" "0.4" 

    上面的步驟是一個函數split_n_select

     split_n_select <- function(x, sel=c(1), pat="\\\\|", nam=c(1:2)){ tmp <- t(colsplit(x, pattern=pat, names=nam)) tmp[sel,] } 
  4. 使用sapply將函數split_n_select應用於linessplit中的每一行

     linessplit2 <- sapply(linessplit, split_n_select) linessplit2 

    結果:

      1 2 3 4 [1,] "A" "B" "0.5" "0.4" [2,] "C" "D" "0.9" "1" [3,] "E" "F" "0.7" "0.2" 
  5. 您還可以通過添加sel = c(2)選擇第二行

     linessplit2 <- sapply(linessplit, split_n_select, sel=c(2)) linessplit2 

    結果:

      1 2 3 4 [1,] "1" "2" NA NA [2,] "3" "4" NA NA [3,] "5" "6" NA NA 

更改

line1 <- linessplit[1]
l1 <- strsplit(line1[1], split = "|")

line1 <- linessplit[1]
l1 <- strsplit(line1[1], split = "[|]") #i added square brackets

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM