我有一个非常大的 csv 文件,其结构如下
123, NAME1, EMAIL1@ADDRESS.COM
111, NAME2, EMAIL2@ADRESS.ME
问题是有些名字有逗号,比如
699, FIRST M. LAST, Jr., EMAIL4@ADDRESS.GOV
有没有办法解决这个问题?原始 csv 有大约 80k 个条目,因此无法手动完成。
谢谢!
我有一个非常大的 csv 文件,其结构如下
123, NAME1, EMAIL1@ADDRESS.COM
111, NAME2, EMAIL2@ADRESS.ME
问题是有些名字有逗号,比如
699, FIRST M. LAST, Jr., EMAIL4@ADDRESS.GOV
有没有办法解决这个问题?原始 csv 有大约 80k 个条目,因此无法手动完成。
谢谢!
在 2 个步骤中,您可以执行此操作,例如:
## read using `fill=TRUE`
dat <- read.table(text='
123, NAME1, EMAIL1@ADDRESS.COM
111, NAME2, EMAIL2@ADRESS.ME
699, FIRST M. LAST, Jr., EMAIL4@ADDRESS.GOV',sep=',',
fill=TRUE,
header=FALSE,stringsAsFactors=FALSE)
## concatenate names when they contain a comma
dat$V3 <- ifelse(nchar(dat$V4)>0,paste(dat$V3,dat$V4,sep=','),dat$V3)
dat[,-4]
V1 V2 V3
1 123 NAME1 EMAIL1@ADDRESS.COM
2 111 NAME2 EMAIL2@ADRESS.ME
3 699 FIRST M. LAST Jr., EMAIL4@ADDRESS.GOV
这是使用正则表达式的 R 解决方案:
file <- textConnection("123, NAME1, EMAIL1@ADDRESS.COM
111, NAME2, EMAIL2@ADRESS.ME
699, FIRST M. LAST, Jr., EMAIL4@ADDRESS.GOV")
lines <- readLines(file)
pattern <- "^(\\d+), (.*), \\b(.*)$"
matches <- regexec(pattern, lines)
bad.rows <- which(sapply(matches, length) == 1L)
if (length(bad.rows) > 0L) stop(paste("bad row: ", lines[bad.rows]))
data <- regmatches(lines, matches)
as.data.frame(matrix(unlist(data), ncol = 4L, byrow = TRUE)[, -1L])
# V1 V2 V3
# 1 123 NAME1 EMAIL1@ADDRESS.COM
# 2 111 NAME2 EMAIL2@ADRESS.ME
# 3 699 FIRST M. LAST, Jr. EMAIL4@ADDRESS.GOV
我使用这个简单的 python 脚本来转换我的数据
import sys
for line in open(sys.argv[1]):
x = line.split(',')
x = [token.strip() for token in x]
x = [x[0], '"%s"' % (",".join(x[1:-1])), x[-1]]
print ";".join(x)
运行它
python conv.py input.txt > output.txt
之后,我可以毫无问题地在 R 中阅读它。
谢谢!
这是一个常见问题,更好的答案之一是使用scan
或readLines
加载整个混乱R
,然后使用gsub
或其他正则表达式工具将行拆分为所需的元素。
编辑:有关此方法的详细信息,请参阅弗洛德尔的回答