Dlaczego dostaję X. w nazwach kolumn podczas czytania ramki danych?

Zadałem pytanie na ten temat kilka miesięcy temu i myślałem, że odpowiedź rozwiązała mój problem, ale wpadłem na problem ponownie i rozwiązanie nie działa dla mnie.

Importuję plik CSV:

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

Oto struktura ramki danych:

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 ...

Jeśli uruchomię length polecenie na pierwszej kolumnie, OrderID, dostaję to:

length(orders$OrderID)
[1] 0

Jeśli uruchamiam length na OrderDate, to zwraca poprawnie:

length(orders$OrderDate)
[1] 3331575

To jest kopiuj / wklej head z CSV.

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

Teraz, jeśli ponownie uruchomię read.csv, ale wyjmę opcję check.names, Pierwsza kolumna dataframe ma teraz X. na początku nazwy.

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

To działa poprawnie.

Moje pytanie brzmi dlaczego R dodaje X. do początku nazwy pierwszej kolumny? Jak widać z pliku CSV, nie ma znaków specjalnych. To powinno być proste obciążenie. Dodanie check.names, while zaimportuje nazwę z pliku CSV, spowoduje dane, które nie ładują się poprawnie, aby wykonać analizę.

Jak mogę to naprawić?

Uwaga na marginesie: zdaję sobie sprawę , że jest to drobne-Jestem bardziej sfrustrowany faktem, że myślę, że Ładuję się poprawnie, ale nie uzyskuję oczekiwanego rezultatu. Mogę zmienić nazwę kolumny używając colnames(orders)[1] <- "OrderID", ale nadal chcę wiedzieć, dlaczego nie ładuje się poprawnie.

Author: smci, 2012-05-04

5 answers

read.csv() jest owijarką wokół bardziej ogólnej funkcji read.table(). Ta ostatnia funkcja ma argument check.names, który jest udokumentowany jako:

check.names: logical.  If ‘TRUE’ then the names of the variables in the
         data frame are checked to ensure that they are syntactically
         valid variable names.  If necessary they are adjusted (by
         ‘make.names’) so that they are, and also to ensure that there
         are no duplicates.

Jeśli nagłówek zawiera etykiety, które nie są poprawne składniowo, to make.names() zastąpi je poprawną nazwą, opartą na nieprawidłowej nazwie, usuwając nieprawidłowe znaki i ewentualnie poprzedzając X:

R> make.names("$Foo")
[1] "X.Foo"

Jest to udokumentowane w ?make.names:

Details:

    A syntactically valid name consists of letters, numbers and the
    dot or underline characters and starts with a letter or the dot
    not followed by a number.  Names such as ‘".2way"’ are not valid,
    and neither are the reserved words.

    The definition of a _letter_ depends on the current locale, but
    only ASCII digits are considered to be digits.

    The character ‘"X"’ is prepended if necessary.  All invalid
    characters are translated to ‘"."’.  A missing value is translated
    to ‘"NA"’.  Names which match R keywords have a dot appended to
    them.  Duplicated values are altered by ‘make.unique’.

Zachowanie, które widzisz, jest całkowicie zgodnie z udokumentowanym sposobem read.table() wczytywania danych. Sugerowałoby to, że w wierszu nagłówka pliku CSV znajdują się niepoprawne składniowo etykiety. Zauważ powyższy punkt ?make.names, że to, co jest literą, zależy od ustawień regionalnych systemu; plik CSV może zawierać poprawny znak, który wyświetli edytor tekstu, ale jeśli R nie jest uruchomiony w tym samym języku, znak ten może nie być tam ważny, na przykład?

Spojrzałbym na plik CSV i zidentyfikowałbym wszelkie Nie-ASCII znaki w linii nagłówka; są prawdopodobnie znaki niewidoczne (lub sekwencje escape; \t?) również w wierszu nagłówka. Wiele może się dziać między odczytaniem w pliku z nieprawidłowymi nazwami a wyświetlaniem go w konsoli, co może maskować niepoprawne znaki, więc nie bierz faktu, że nie pokazuje on niczego złego bez check.names jako wskazującego, że plik jest w porządku.

Opublikowanie wyjścia sessionInfo() byłoby również przydatne.

 81
Author: Gavin Simpson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-04 09:48:04

Właśnie natknąłem się na ten problem i to z prostego powodu. Miałem etykiety, które zaczynały się od numeru, A R dodawało przed nimi X. Myślę, że R jest mylony z liczbą w nagłówku i stosuje literę w celu odróżnienia od wartości.

Tak więc "3_in "stał się" X3_in " itd... Rozwiązałem zmieniając etykietę na "in_3" i problemy zostały rozwiązane.

Mam nadzieję, że to komuś pomoże.

 12
Author: Matt Beam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-29 19:53:18

Przejechałem podobny problem i chciałem udostępnić następujące linie kodu, aby poprawić nazwy kolumn. Na pewno nie idealnie, bo czyste programowanie w forehandu byłoby lepsze, ale może pomocny jako punkt wyjścia dla kogoś tak szybkiego i brudnego podejścia. (Chciałbym dodać je jako komentarz do pytania Ryana/odpowiedzi Gavina, ale moja reputacja nie jest wystarczająco wysoka, więc musiałem dodać dodatkową odpowiedź-przepraszam).

W moim przypadku kilka kroków zapisu i odczytu danych wytworzono jedną lub więcej kolumn o nazwach "X", X. 1",... zawierające treść w kolumnie X i numery wierszy w X. 1,...- kolumny. W moim przypadku zawartość kolumny X powinna być używana jako nazwy wierszy, a pozostałe X. 1,...- kolumny powinny zostać usunięte.

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
Author: Manuel Bickel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-01 11:08:12

Gdy nazwy kolumn nie mają poprawnej formy, r umieść "X" na początku nazwy kolumny podczas importu. Na przykład zwykle dzieje się tak, gdy nazwy kolumn zaczynają się od liczby lub jakiegoś znaku spacji. check.names = FALSE ponieważ tak się nie stanie - nie będzie "X". Jednak niektóre funkcje mogą nie działać, jeśli nazwy kolumn zaczynają się od liczb lub innego znaku specjalnego. Przykładem jest rbind.fill function.

Więc po zastosowaniu tej funkcji (z "poprawionymi nazwami") I użyj tej prostej rzeczy, aby pozbyć się "X".

destroyX = function(es) {
  f = es
  for (col in c(1:ncol(f))){ #for each column in dataframe
    if (startsWith(colnames(f)[col], "X") == TRUE)  { #if starts with 'X' ..
      colnames(f)[col] <- substr(colnames(f)[col], 2, 100) #get rid of it
    }
  }
  assign(deparse(substitute(es)), f, inherits = TRUE) #assign corrected data to original name
}
 5
Author: Dorregaray,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-11-20 10:06:36

Rozwiązałem podobny problem, włączając row.names=FALSE jako argument w funkcji write.csv. write.csv włączała nazwy wierszy jako nienazwaną kolumnę w pliku CSV, a read.csv nazywała tę kolumnę " X " podczas odczytu pliku CSV.

 4
Author: Tristan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-05-23 13:00:13