R如何根据条件读取文本文件
R how to read text file based on condition
我是 R 的初学者,我有一个像这样的大 txt 文件:
1:
123,3,2002-09-06
456,2,2005-08-13
789,4,2001-09-20
2:
123,5,2003-05-08
321,1,2004-06-15
432,3,2001-09-11
带':'的行是itemID,后面几行是UserID,Quantity和Date
我想这样读成data.frame:
itemID UserID Quantity Date
1 123 3 2002-09-06
1 456 2 2005-08-13
1 789 4 2001-09-20
2 123 5 2003-05-08
2 321 1 2004-06-15
2 432 3 2001-09-11
可以用read.csv实现吗?或者如何按条件读取这个文件?
如有任何帮助,我们将不胜感激。
read.table()
将无法轻松阅读此内容。 R 期望大多数数据数据是干净的和矩形的。
您可以将数据读取为一堆行,将这些行处理为更规则的格式,然后使用 read.table
对其进行解析。例如
# Read your data file
# xx <- readLines("mydatafile.txt")
# for the sake of a complete example
xx <- scan(text="1:
123,3,2002-09-06
456,2,2005-08-13
789,4,2001-09-20
2:
123,5,2003-05-08
321,1,2004-06-15
432,3,2001-09-11", what=character())
这会将行作为字符串读入。然后你可以分成几组并将项目 ID 作为另一个值附加到每一行
item_group <- cumsum(grepl("\d+:", xx))
clean_rows <- unlist(lapply(split(xx, item_group), function(x) {
item_id = gsub(":$",",", x[1])
paste0(item_id, x[-1])
}))
然后你可以将数据解析成data.frame
read.table(text=clean_rows, sep=",", col.names=c("itemID","UserID","Quantity","Date"))
这是一个解决方案。这是相当手动的,在这个例子中有很多东西要解压...
separator_pattern <- "^(\d+):\s*$"
block_text <- out <- NULL
for(line in readLines(file("~/temp/example.txt"))){
if(grepl(separator_pattern,line)){
if(!is.null(block_text)){
txt <- paste(c(paste0("column",1:3,collapse = ", "), block_text), collapse="\n")
tmp <- cbind("block" = block_no, read.csv(textConnection(txt)))
out <- rbind(out,tmp)
}
block_no <- as.numeric(gsub(separator_pattern,"\1",line))
print(block_no)
block_text <- character(0)
}else{
block_text <- c(block_text,line)
}
}
txt <- paste(c(paste0("column",1:3,collapse = ", "), block_text), collapse="\n")
tmp <- cbind("block" = block_no, read.csv(textConnection(txt)))
out <- rbind(out,tmp)
显然这假定您的文件位于 path.expand("~/temp/example.txt")
我是 R 的初学者,我有一个像这样的大 txt 文件:
1:
123,3,2002-09-06
456,2,2005-08-13
789,4,2001-09-20
2:
123,5,2003-05-08
321,1,2004-06-15
432,3,2001-09-11
带':'的行是itemID,后面几行是UserID,Quantity和Date
我想这样读成data.frame:
itemID UserID Quantity Date
1 123 3 2002-09-06
1 456 2 2005-08-13
1 789 4 2001-09-20
2 123 5 2003-05-08
2 321 1 2004-06-15
2 432 3 2001-09-11
可以用read.csv实现吗?或者如何按条件读取这个文件?
如有任何帮助,我们将不胜感激。
read.table()
将无法轻松阅读此内容。 R 期望大多数数据数据是干净的和矩形的。
您可以将数据读取为一堆行,将这些行处理为更规则的格式,然后使用 read.table
对其进行解析。例如
# Read your data file
# xx <- readLines("mydatafile.txt")
# for the sake of a complete example
xx <- scan(text="1:
123,3,2002-09-06
456,2,2005-08-13
789,4,2001-09-20
2:
123,5,2003-05-08
321,1,2004-06-15
432,3,2001-09-11", what=character())
这会将行作为字符串读入。然后你可以分成几组并将项目 ID 作为另一个值附加到每一行
item_group <- cumsum(grepl("\d+:", xx))
clean_rows <- unlist(lapply(split(xx, item_group), function(x) {
item_id = gsub(":$",",", x[1])
paste0(item_id, x[-1])
}))
然后你可以将数据解析成data.frame
read.table(text=clean_rows, sep=",", col.names=c("itemID","UserID","Quantity","Date"))
这是一个解决方案。这是相当手动的,在这个例子中有很多东西要解压...
separator_pattern <- "^(\d+):\s*$"
block_text <- out <- NULL
for(line in readLines(file("~/temp/example.txt"))){
if(grepl(separator_pattern,line)){
if(!is.null(block_text)){
txt <- paste(c(paste0("column",1:3,collapse = ", "), block_text), collapse="\n")
tmp <- cbind("block" = block_no, read.csv(textConnection(txt)))
out <- rbind(out,tmp)
}
block_no <- as.numeric(gsub(separator_pattern,"\1",line))
print(block_no)
block_text <- character(0)
}else{
block_text <- c(block_text,line)
}
}
txt <- paste(c(paste0("column",1:3,collapse = ", "), block_text), collapse="\n")
tmp <- cbind("block" = block_no, read.csv(textConnection(txt)))
out <- rbind(out,tmp)
显然这假定您的文件位于 path.expand("~/temp/example.txt")