我有大约3.000个CSV文件(包含推文),格式相同,我想将这些文件合并为一个新文件并删除重复的推文。我遇到过讨论类似问题的各种主题,但文件数量通常很少。我希望你能帮我在R中编写一个能够高效,有效地完成这项工作的代码。
CSV文件格式如下:
CSV格式的图片:
我将(在第2和第3列)用户名(在Twitter上)更改为A-E,将“实际名称”更改为A1-E1。
原始文本文件:
"tweet";"author";"local.time"
"1";"2012-06-05 00:01:45 @A (A1): Cruijff z'n met-zwart-shirt-zijn-ze-onzichtbaar logica is even mooi ontkracht in #bureausport.";"A (A1)";"2012-06-05 00:01:45"
"2";"2012-06-05 00:01:41 @B (B1): Welterusten #BureauSport";"B (B1)";"2012-06-05 00:01:41"
"3";"2012-06-05 00:01:38 @C (C1): Echt ..... eindelijk een origineel sportprogramma #bureausport";"C (C1)";"2012-06-05 00:01:38"
"4";"2012-06-05 00:01:38 @D (D1): LOL. \"Na onderzoek op de Fontys Hogeschool durven wij te stellen dat..\" Want Fontys staat zo hoog aangeschreven? #bureausport";"D (D1)";"2012-06-05 00:01:38"
"5";"2012-06-05 00:00:27 @E (E1): Ik kijk Bureau sport op Nederland 3. #bureausport #kijkes";"E (E1)";"2012-06-05 00:00:27"
不知怎的,我的标题搞砸了,显然它们应该向右移动一列。每个CSV文件最多包含1500条推文。我想通过检查第二列(包含推文)来删除重复项,因为这些应该是唯一的,并且作者列可以是相似的(例如,一位作者发布多条推文)。
是否可以合并文件并删除重复项,或者这是否有问题并且流程是否应该分开?作为起点,我在Hayward Godwin的两个博客中加入了两个链接,讨论了合并CSV文件的三种方法。
显然,在我的网站上也有一些与我的问题相关的主题(例如Merging multiple csv files in R),但我没有找到任何讨论合并和删除重复项的内容。我真的希望你能帮助我和我有限的R知识来应对这一挑战!
虽然我已经尝试了一些我在网上找到的代码,但这实际上并没有产生输出文件。大约3.000个CSV文件具有上述格式。我的意思是尝试以下代码(对于合并部分):
filenames <- list.files(path = "~/")
do.call("rbind", lapply(filenames, read.csv, header = TRUE))
这会导致以下错误:
Error in file(file, "rt") : cannot open the connection
In addition: Warning message:
In file(file, "rt") :
cannot open file '..': No such file or directory
更新
我尝试过以下代码:
# grab our list of filenames
filenames <- list.files(path = ".", pattern='^.*\\.csv$')
# write a special little read.csv function to do exactly what we want
my.read.csv <- function(fnam) { read.csv(fnam, header=FALSE, skip=1, sep=';', col.names=c('ID','tweet','author','local.time'), colClasses=rep('character', 4)) }
# read in all those files into one giant data.frame
my.df <- do.call("rbind", lapply(filenames, my.read.csv))
# remove the duplicate tweets
my.new.df <- my.df[!duplicated(my.df$tweet),]
但是我遇到了以下错误:
在第3行之后我得到了:
Error in read.table(file = file, header = header, sep = sep, quote = quote, : more columns than column names
在第4行之后我得到了:
Error: object 'my.df' not found
我怀疑这些错误是由csv文件的写入过程中的一些失败引起的,因为有些情况下作者/ local.time在错误的列中。在它们应该到达的位置的左侧或右侧,这会产生额外的列。我手动调整了5个文件,并测试了这些文件的代码,我没有收到任何错误。然而它似乎根本没有发生任何事情。我没有从R获得任何输出?
为了解决额外的列问题,我稍微调整了代码:
#grab our list of filenames
filenames <- list.files(path = ".", pattern='^.*\\.csv$')
# write a special little read.csv function to do exactly what we want
my.read.csv <- function(fnam) { read.csv(fnam, header=FALSE, skip=1, sep=';', col.names=c('ID','tweet','author','local.time','extra'), colClasses=rep('character', 5)) }
# read in all those files into one giant data.frame
my.df <- do.call("rbind", lapply(filenames, my.read.csv))
# remove the duplicate tweets
my.new.df <- my.df[!duplicated(my.df$tweet),]
我在所有文件上尝试了这个代码,虽然R明显开始处理,但我最终得到了以下错误:
Error in read.table(file = file, header = header, sep = sep, quote = quote, : more columns than column names
In addition: Warning messages:
1: In read.table(file = file, header = header, sep = sep, quote = quote, : incomplete final line found by readTableHeader on 'Twitts - di mei 29 19_22_30 2012 .csv'
2: In read.table(file = file, header = header, sep = sep, quote = quote, : incomplete final line found by readTableHeader on 'Twitts - di mei 29 19_24_31 2012 .csv'
Error: object 'my.df' not found
我做错了什么?
答案 0 :(得分:7)
首先,通过放在文件所在的文件夹中来简化问题,并尝试将模式设置为只读取文件结尾为“.csv”的文件,所以类似
filenames <- list.files(path = ".", pattern='^.*\\.csv$')
my.df <- do.call("rbind", lapply(filenames, read.csv, header = TRUE))
这应该会为您提供包含所有推文内容的data.frame
另一个问题是csv文件中的标头。谢天你知道所有文件都是相同的,所以我会处理这样的事情:
read.csv('fred.csv', header=FALSE, skip=1, sep=';',
col.names=c('ID','tweet','author','local.time'),
colClasses=rep('character', 4))
的Nb。改变所以所有列都是字符,';'分离
如果需要,我会在稍后解析时间......
另一个单独的问题是data.frame中推文的唯一性 - 但我不清楚你是希望它们对用户是唯一的还是全局唯一的。对于全球唯一的推文,例如
my.new.df <- my.df[!duplicated(my.df$tweet),]
对于作者的独特,我会追加这两个字段 - 很难知道在没有真实数据的情况下哪些方法有效!
my.new.df <- my.df[!duplicated(paste(my.df$tweet, my.df$author)),]
所以把它们全部放在一起,并假设一些事情......
# grab our list of filenames
filenames <- list.files(path = ".", pattern='^.*\\.csv$')
# write a special little read.csv function to do exactly what we want
my.read.csv <- function(fnam) { read.csv(fnam, header=FALSE, skip=1, sep=';',
col.names=c('ID','tweet','author','local.time'),
colClasses=rep('character', 4)) }
# read in all those files into one giant data.frame
my.df <- do.call("rbind", lapply(filenames, my.read.csv))
# remove the duplicate tweets
my.new.df <- my.df[!duplicated(my.df$tweet),]
根据第3行之后的修订警告,对于具有不同列数的文件存在问题。这通常不容易修复,除非您通过在规范中包含太多列来建议。如果您删除了规范,那么当您尝试将data.frames一起rbind()时,您将遇到问题......
下面是一些使用for()循环和一些调试cat()语句的代码,以便更明确地删除哪些文件,以便您可以修复:
filenames <- list.files(path = ".", pattern='^.*\\.csv$')
n.files.processed <- 0 # how many files did we process?
for (fnam in filenames) {
cat('about to read from file:', fnam, '\n')
if (exists('tmp.df')) rm(tmp.df)
tmp.df <- read.csv(fnam, header=FALSE, skip=1, sep=';',
col.names=c('ID','tweet','author','local.time','extra'),
colClasses=rep('character', 5))
if (exists('tmp.df') & (nrow(tmp.df) > 0)) {
cat(' successfully read:', nrow(tmp.df), ' rows from ', fnam, '\n')
# now lets append a column containing the originating file name
# so that debugging the file contents is easier
tmp.df$fnam <- fnam
# now lets rbind everything together
if (exists('my.df')) {
my.df <- rbind(my.df, tmp.df)
} else {
my.df <- tmp.df
}
} else {
cat(' read NO rows from ', fnam, '\n')
}
}
cat('processed ', n.files.processed, ' files\n')
my.new.df <- my.df[!duplicated(my.df$tweet),]