将csv文件读入R,其中包含每行开头和结尾的括号

时间:2014-07-07 14:18:24

标签: r csv

我有一个文本文件,如下所示

(abc,123)
(def,456)
(ghi,789)
...

在R中,我想将此文件作为csv读取。因此,我需要摆脱行尾的开始和结束括号。你知道如何实现这个目标吗?

如果可能的话,应该避免读取文件,删除括号并写入临时文件。

6 个答案:

答案 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