2012-06-09 6 views
4

У меня есть почти 3.000 CSV-файлов (содержащих твиты) в том же формате, я хочу объединить эти файлы в один новый файл и удалить дублированные твиты. Я столкнулся с различными темами, обсуждая похожие вопросы, однако количество файлов обычно заканчивается небольшим. Надеюсь, вы можете помочь мне написать код внутри R, который эффективно и эффективно выполняет эту работу.Объединить несколько файлов CSV и удалить дубликаты в R

Файлы CSV имеют следующий формат:

изображение формата CSV: Example CSV files

Я изменил (в колонке 2 и 3) имена пользователей (на Twitter) в АЕ и «фактические имена» к 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 твитов. Я хотел бы удалить дубликаты, проверив второй столбец (содержащий твиты) просто потому, что они должны быть уникальными, а столбцы автора могут быть похожими (например, один автор публикует несколько твитов).

Возможно ли совместить слияние файлов и удаление дубликатов, или это задает проблемы, и должны ли процессы разделяться? В качестве отправной точки я включил две ссылки двух блогов от Хейворда Годвина, в которых обсуждались три подхода к объединению файлов CSV.

http://psychwire.wordpress.com/2011/06/03/merge-all-files-in-a-directory-using-r-into-a-single-dataframe/

http://psychwire.wordpress.com/2011/06/05/testing-different-methods-for-merging-a-set-of-files-into-a-dataframe/

Очевидно, что некоторые темы, связанные с моим вопросом на этом сайте, а также (например, 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 

Update

Я попытался следующий код:

# 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),] 

Но я столкнулся с t он следующие ошибки:

После 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-файлов, так как есть некоторые случаи, когда author/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

Показать код, который вы используете. Возможно, вы отправляете неверный аргумент 'header' в свой' read.csv() '. – Andrie

+0

Ваш вопрос достаточно ясен, но неясно, что вы сделали до сих пор и почему это не работает. Покажите вызов 'read.csv()', который вы используете для чтения файла. Затем мы можем прокомментировать, что вы делаете неправильно. – Andrie

+0

Я отредактировал мой вопрос, надеюсь, что это то, что ваш после? – Gert

ответ

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, это проблема с файлами с разным количеством колонок. Это нелегко исправить вообще, за исключением того, что вы предложили, имея слишком много столбцов в спецификации. Если вы удалите спецификацию, тогда вы столкнетесь с проблемами при попытке rbind() data.frames вместе ...

Вот какой код использует цикл 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),] 
+0

Thnx Sean, даст это завтра! В папке есть только файлы .csv, поэтому часть шаблона кажется ненужной. – Gert

+0

У меня было некоторое время, чтобы сэкономить, и поэтому решил проверить ваше предложение Шона. Я получил следующую ошибку после попытки первой части кода. Ошибка в read.table (file = file, header = header, sep = sep, quote = quote,: больше столбцов, чем имена столбцов – Gert

+0

Привет, вы могли бы опубликовать первые несколько строк одного из ваших файлов csv (при условии, что все в порядке) и укажите, имеют ли все они одинаковый формат? –

Смежные вопросы