[英]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"
有沒有人有辦法解決這個問題? 謝謝!
由於您提供了一種方法,我解釋了代碼中的錯誤,即使對於您的問題,也許您必須考慮另一種方法。 無論如何,拋開個人對代碼的品味,問題是:
line1[[1]]
提取列表的第一個元素 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
這是打破它:
將原始數據讀入行
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"
加載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
這是一個函數來取一行,分成行並選擇我們想要的行。
把第一排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,] }
使用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"
您還可以通過添加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.