我有一个文本文件,如下所示
(abc,123)
(def,456)
(ghi,789)
...
在R中,我想将此文件作为csv读取。因此,我需要摆脱行尾的开始和结束括号。你知道如何实现这个目标吗?
如果可能的话,应该避免读取文件,删除括号并写入临时文件。
答案 0 :(得分:6)
好的,这似乎有效(在我的Mac上):
read.table(pipe("tr -d '()' < ~/Desktop/paren.txt"),header = FALSE,sep = ",")
V1 V2
1 123 abc
2 456 def
3 789 ghi
答案 1 :(得分:4)
疯狂的创意时间,但您可以创建自己的colClasses
定义并在read.table
中使用它们,如下所示:
setClass("strippedL")
setClass("strippedR")
setAs("character", "strippedL",
function(from) as.character( gsub("(", "", from, fixed=TRUE)))
setAs("character", "strippedR",
function(from) as.numeric( gsub(")", "", from, fixed=TRUE)))
以下是它的使用方法。将text
参数替换为file
参数以代替访问文件。
read.table(text = "(abc,123)
(def,456)
(ghi,789)",
sep = ",", header = FALSE,
colClasses = c("strippedL", "strippedR"))
# V1 V2
# 1 abc 123
# 2 def 456
# 3 ghi 789
不那么疯狂(但速度较慢)的想法:从&#34; gsubfn&#34;的开发版本中试用read.pattern
:
library(gsubfn)
source("http://gsubfn.googlecode.com/svn/trunk/R/read.pattern.R")
pat <- "^\\((.*),(.*)\\)$"
read.pattern("~/path/to/file.txt", pattern=pat, header = FALSE)
答案 2 :(得分:3)
我可能会去readLines
路由,因为文件需要先被操作。然后,您仍然可以使用text
read.csv/table
参数
> writeLines(c("(abc,123)", "(def,456)", "(ghi,789)"), "yourfile.txt")
## put your data in a file
> txt <- gsub("[()]", "", readLines("yourfile.txt"))
> read.csv(text = txt, header = FALSE)
# V1 V2
# 1 abc 123
# 2 def 456
# 3 ghi 789
或
> read.table(text = txt, sep = ",")
# V1 V2
# 1 abc 123
# 2 def 456
# 3 ghi 789
答案 3 :(得分:1)
坦率地说,处理这种情况的最佳方法是在将源文件读入R
之前编辑源文件。我可以想象没有理由避免这样做,保证写一些花哨的R
代码,以便在读取数据后删除括号。
打开您选择的文本编辑器并告诉它(编辑器)删除所有括号。保存文件(如有必要,保存到新文件),然后使用read.csv
打开新文件。
但如果你必须,
foo<- read.csv(your_file)
gsub('(','',foo)
gsub(')','',foo)
foo[,2]<-as.numeric(foo[,2])
编辑:进行了速度测试:
paren1<-function(file) {
foo<- read.csv(file)
gsub('[()]','',foo)
#gsub(')','',foo)
foo[,2]<-as.numeric(foo[,2])
}
setClass("strippedL")
setClass("strippedR")
setAs("character", "strippedL",
function(from) as.character( gsub("(", "", from, fixed=TRUE)))
setAs("character", "strippedR",
function(from) as.numeric( gsub(")", "", from, fixed=TRUE)))
paren2<-function(file) {
foo<- read.table(file,sep = ",", header = FALSE, colClasses = c("strippedL", "strippedR"))
return(invisible(foo))
}
library(microbenchmark)
# my "paren.txt" has 860 lines in it
microbenchmark(paren1('paren.txt'),paren2('paren.txt'))
Unit: milliseconds
expr min lq median uq max neval
paren1("paren.txt") 3.341024 3.461614 3.486416 3.514639 4.060715 100
paren2("paren.txt") 2.164631 2.251439 2.285007 2.322211 5.681836 100
所以Ananda的解决方案显然更快。哦,好吧:-)
答案 4 :(得分:1)
你可以尝试:
str1 <- c("(abc,123)","(def,456)","(ghi,789)")
library(qdap)
read.table(text=unlist(bracketXtract(str1, "round")),sep=",")
# V1 V2
#1 abc 123
#2 def 456
#3 ghi 789
答案 5 :(得分:0)
这是一个使用gsub
函数的选项,用于data.frame的第一列和第二列:
tmp <- read.table("tmp.csv", sep=",", stringsAsFactors=FALSE)
#tmp <- structure(list(V1 = c("(abc", "(def", "(ghi"), V2 = c("123)",
"456)", "789)")), .Names = c("V1", "V2"), class = "data.frame", row.names = c(NA,
-3L)) # to reproduce tmp
tmp
tmp[,1] <- gsub("(", "", tmp[,1], fixed = TRUE)
tmp[,2] <- gsub(")", "", tmp[,2], fixed = TRUE)
tmp