web-dev-qa-db-ja.com

データフレームを読み取るときに列名にXが表示されるのはなぜですか?

数か月前の質問 を尋ねたところ、答えが私の問題を解決したと思ったが、再び問題にぶつかり、解決策がうまくいかなかった。

CSVをインポートしています:

_orders <- read.csv("<file_location>", sep=",", header=T, check.names = FALSE)
_

データフレームの構造は次のとおりです。

_str(orders)

'data.frame':   3331575 obs. of  2 variables:
 $ OrderID  : num  -2034590217 -2034590216 -2031892773 -2031892767 -2021008573 ...
 $ OrderDate: Factor w/ 402 levels "2010-10-01","2010-10-04",..: 263 263 269 268 301 300 300 300 300 300 ...
_

最初の列であるOrderIDでlengthコマンドを実行すると、次のようになります。

_length(orders$OrderID)
[1] 0
_

OrderDateでlengthを実行すると、正しく返されます。

_length(orders$OrderDate)
[1] 3331575
_

これは、headCSVのコピー/貼り付けです。

_OrderID,OrderDate
-2034590217,2011-10-14
-2034590216,2011-10-14
-2031892773,2011-10-24
-2031892767,2011-10-21
-2021008573,2011-12-08
-2021008572,2011-12-07
-2021008571,2011-12-07
-2021008570,2011-12-07
-2021008569,2011-12-07
_

ここで、_read.csv_を再実行し、_check.names_オプションを削除すると、dataframeの最初の列の名前の先頭にXが付きます。

_orders2 <- read.csv("<file_location>", sep=",", header=T)

str(orders2)

'data.frame':   3331575 obs. of  2 variables:
 $ X.OrderID: num  -2034590217 -2034590216 -2031892773 -2031892767 -2021008573 ...
 $ OrderDate: Factor w/ 402 levels "2010-10-01","2010-10-04",..: 263 263 269 268 301 300 300 300 300 300 ...

length(orders$X.OrderID)
[1] 3331575
_

これは正常に機能します。

私の質問は、Rが最初の列名の先頭にXを追加するのはなぜですか? CSVファイルからわかるように、特殊文字はありません。単純な負荷である必要があります。 _check.names_を追加すると、CSVから名前がインポートされますが、分析を実行するためにデータが正しくロードされません。

これを修正するにはどうすればよいですか?

サイドノート:私はこれがマイナーであることを認識しています-私はちょうど私が正しくロードしていると思っているという事実にもっとイライラしていますが、期待した結果を得ていません。 colnames(orders)[1] <- "OrderID"を使用して列の名前を変更できましたが、それでもなぜ正しくロードされないのかを知りたいです。

52
mikebmassey

私はこの問題に出くわしましたが、それは簡単な理由でした。番号で始まるラベルがあり、Rはそれらの前にXを追加していました。 Rはヘッダー内の数字と混同されており、値と区別するために文字を適用していると思います。

したがって、「3_in」は「X3_in」などになりました。ラベルを「in_3」に切り替えることで解決し、問題は解決しました。

これが誰かの助けになることを願っています。

10
Matt Beam

同様の問題に出くわし、列名を修正するために次のコード行を共有したいと考えました。確かに完璧ではありません。フォアハンドでのきれいなプログラミングの方が良いでしょうが、誰かへの出発点として迅速で汚いアプローチとして役立つかもしれません。 (ライアンの質問/ギャビンの回答にコメントとして追加したかったのですが、私の評判が十分に高くないため、追加の回答を投稿する必要がありました-申し訳ありません)。

私の場合、データの書き込みと読み取りのいくつかのステップで、X列のコンテンツとX.1、...列の行番号を含む「X」、X.1」、...という名前の1つ以上の列が生成されました。私の場合、X列のコンテンツを行名として使用し、他のX.1、...列を削除する必要があります。

Correct_Colnames <- function(df) {

 delete.columns <- grep("(^X$)|(^X\\.)(\\d+)($)", colnames(df), Perl=T)

  if (length(delete.columns) > 0) {

   row.names(df) <- as.character(df[, grep("^X$", colnames(df))])
   #other data types might apply than character or 
   #introduction of a new separate column might be suitable

   df <- df[,-delete.columns]

   colnames(df) <- gsub("^X", "",  colnames(df))
   #X might be replaced by different characters, instead of being deleted
  }

  return(df)
}
7
Manuel Bickel

Write.csv関数の引数としてrow.names = FALSEを含めることで、同様の問題を解決しました。 write.csvはCSVファイルの名前のない列として行名を含め、read.csvはCSVファイルを読み取るときにその列に「X」という名前を付けていました。

3
Tristan