5

同じ形式のCSVファイル(ツイートを含む)が約3.000ありますが、これらのファイルを1つの新しいファイルにマージして、重複するツイートを削除したいと思います。私は同様の質問を議論するさまざまなトピックに出くわしましたが、ファイルの数は通常かなり少ないです。この仕事を効率的かつ効果的に行うR内のコードを書くのを手伝ってくれることを願っています。

CSVファイルの形式は次のとおりです。

CSV形式の画像: CSVファイルの例

(2列目と3列目で)ユーザー名(Twitter)をAEに変更し、「実際の名前」を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"

どういうわけか私のヘッダーはめちゃくちゃです、それらは明らかに1列右に移動するはずです。各CSVファイルには最大1500件のツイートが含まれています。2番目の列(ツイートを含む)をチェックして重複を削除したいのは、これらが一意であり、作成者の列が類似している可能性があるためです(たとえば、1人の作成者が複数のツイートを投稿している)。

ファイルのマージと重複の削除を組み合わせることができますか、それとも問題が発生するので、プロセスを分離する必要がありますか?出発点として、CSVファイルをマージするための3つのアプローチについて説明しているHaywardGodwinの2つのブログに2つのリンクを含めました。

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/

明らかに、このサイトにも私の質問に関連するトピックがいくつかあります(たとえば、Rで複数のcsvファイルをマージする)が、重複のマージと削除の両方について説明しているものは見つかりませんでした。私と私の限られたRの知識がこの課題に対処するのを手伝ってくれることを本当に願っています!

Webで見つけたいくつかのコードを試しましたが、実際には出力ファイルにはなりませんでした。約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

これらのエラーは、author / local.timeが間違った列にある場合があるため、csvファイルの書き込みプロセスで発生したいくつかの失敗が原因であると思われます。本来あるべき場所の左側または右側にあるため、余分な列が作成されます。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

私は何を間違えましたか?

4

1 に答える 1

8

まず、ファイルがあるフォルダーに移動して問題を単純化し、ファイルが「.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),]

著者による独自性のために、2つのフィールドを追加します-実際のデータなしで何が機能するかを知るのは難しいですが!

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),]
于 2012-06-09T15:55:47.333 に答える