it-swarm.com.de

Wie liest man Daten, wenn einige Zahlen als Tausendertrennzeichen Kommas enthalten?

Ich habe eine CSV-Datei, in der einige der numerischen Werte als Zeichenfolgen mit Kommas als Tausendertrennzeichen ausgedrückt werden, z. "1,513" statt 1513. Was ist der einfachste Weg, um die Daten in R einzulesen?

Ich kann read.csv(..., colClasses="character") verwenden, aber dann muss ich die Kommas aus den relevanten Elementen entfernen, bevor diese Spalten in numerische Zeichen umgewandelt werden.

103
Rob Hyndman

Ich möchte R verwenden, anstatt die Daten vorzuverarbeiten, da dies die Überarbeitung der Daten erleichtert. Dem Vorschlag von Shane folgend, gsub zu verwenden, denke ich, dass dies so ordentlich ist, wie ich es tun kann:

x <- read.csv("file.csv",header=TRUE,colClasses="character")
col2cvt <- 15:41
x[,col2cvt] <- lapply(x[,col2cvt],function(x){as.numeric(gsub(",", "", x))})
16
Rob Hyndman

Sie sind nicht sicher, wie read.csv sie richtig interpretieren soll, aber Sie können gsub verwenden, um "," durch "" zu ersetzen, und dann die Zeichenfolge mit as.numeric in numeric konvertieren.

y <- c("1,200","20,000","100","12,111")
as.numeric(gsub(",", "", y))
# [1]  1200 20000 100 12111

Dies wurde auch vorher auf R-Help (und in Q2 hier ) beantwortet.

Alternativ können Sie die Datei vorverarbeiten, zum Beispiel mit sed in Unix.

125
Shane

Sie können read.table oder read.csv diese Konvertierung halbautomatisch für Sie durchführen lassen. Erstellen Sie zuerst eine neue Klassendefinition, dann eine Konvertierungsfunktion und legen Sie sie als "as" -Methode fest, indem Sie die setAs-Funktion wie folgt verwenden:

setClass("num.with.commas")
setAs("character", "num.with.commas", 
        function(from) as.numeric(gsub(",", "", from) ) )

Führen Sie dann read.csv wie folgt aus:

DF <- read.csv('your.file.here', 
   colClasses=c('num.with.commas','factor','character','numeric','num.with.commas'))
52
Greg Snow

Diese Frage ist mehrere Jahre alt, aber ich bin darauf gestoßen, was vielleicht bedeutet, dass andere es tun werden.

Das Paket readr library/enthält einige nette Funktionen. Eine davon ist eine nette Art, "unordentliche" Spalten wie diese zu interpretieren.

library(readr)
read_csv("numbers\n800\n\"1,800\"\n\"3500\"\n6.5",
          col_types = list(col_numeric())
        )

Dies ergibt

Quelle: Lokaler Datenrahmen [4 x 1]

  numbers
    (dbl)
1   800.0
2  1800.0
3  3500.0
4     6.5

Ein wichtiger Punkt beim Einlesen von Dateien: Sie müssen entweder eine Vorverarbeitung durchführen, wie der Kommentar zu sed oben, oder Sie müssen verarbeiten, während Sie lesen. Wenn Sie versuchen, Dinge nachträglich zu korrigieren, werden oft gefährliche Annahmen gemacht, die schwer zu finden sind. (Deshalb sind flache Dateien an erster Stelle so böse.)

Wenn ich zum Beispiel den col_types nicht markiert hätte, hätte ich Folgendes erhalten:

> read_csv("numbers\n800\n\"1,800\"\n\"3500\"\n6.5")
Source: local data frame [4 x 1]

  numbers
    (chr)
1     800
2   1,800
3    3500
4     6.5

(Beachten Sie, dass es jetzt eine chr (character) anstelle einer numeric ist.)

Oder gefährlicher, wenn es lang genug war und die meisten frühen Elemente keine Kommas enthielten:

> set.seed(1)
> tmp <- as.character(sample(c(1:10), 100, replace=TRUE))
> tmp <- c(tmp, "1,003")
> tmp <- paste(tmp, collapse="\"\n\"")

(so dass die letzten Elemente aussehen :)

\"5\"\n\"9\"\n\"7\"\n\"1,003"

Dann werden Sie Schwierigkeiten haben, dieses Komma zu lesen!

> tail(read_csv(tmp))
Source: local data frame [6 x 1]

     3"
  (dbl)
1 8.000
2 5.000
3 5.000
4 9.000
5 7.000
6 1.003
Warning message:
1 problems parsing literal data. See problems(...) for more details. 
11
Mike Williamson

"Vorverarbeitung" in R:

lines <- "www, rrr, 1,234, ttt \n rrr,zzz, 1,234,567,987, rrr"

Kann readLines für eine textConnection verwenden. Entfernen Sie dann nur die Kommas zwischen den Ziffern:

gsub("([0-9]+)\\,([0-9])", "\\1\\2", lines)

## [1] "www, rrr, 1234, ttt \n rrr,zzz, 1234567987, rrr"

Es ist auch nützlich zu wissen, aber nicht direkt relevant für diese Frage, dass Kommas als Dezimaltrennzeichen von read.csv2 (automagically) oder read.table (mit Einstellung des 'dec'-Parameters) behandelt werden können. 

Edit: Später entdeckte ich, wie man colClasses verwendet, indem ich eine neue Klasse entwarf. Sehen:

Wie kann man df mit 1000 Trennzeichen in R als numerische Klasse laden?

6
42-

eine dplyr-Lösung mit mutate_all und Pipes

sagen Sie haben folgendes:

> dft
Source: local data frame [11 x 5]

   Bureau.Name Account.Code   X2014   X2015   X2016
1       Senate          110 158,000 211,000 186,000
2       Senate          115       0       0       0
3       Senate          123  15,000  71,000  21,000
4       Senate          126   6,000  14,000   8,000
5       Senate          127 110,000 234,000 134,000
6       Senate          128 120,000 159,000 134,000
7       Senate          129       0       0       0
8       Senate          130 368,000 465,000 441,000
9       Senate          132       0       0       0
10      Senate          140       0       0       0
11      Senate          140       0       0       0

und möchten Kommas aus den Jahresvariablen X2014-X2016 entfernen, und in numerische konvertieren. Nehmen wir auch an, X2014-X2016 wird als Faktoren eingelesen (Standard).

dft %>%
    mutate_all(funs(as.character(.)), X2014:X2016) %>%
    mutate_all(funs(gsub(",", "", .)), X2014:X2016) %>%
    mutate_all(funs(as.numeric(.)), X2014:X2016)

mutate_all wendet die Funktion (en) in funs auf die angegebenen Spalten an

Ich habe es nacheinander jeweils eine Funktion ausgeführt (wenn Sie mehrere Funktionen in funs verwenden, erstellen Sie zusätzliche, unnötige Spalten)

5
Paul

Wenn die Nummer durch "." Getrennt ist und Dezimalzahlen durch "," (1.200.000,00) beim Aufruf von gsub müssen Sie set fixed=TRUE as.numeric(gsub(".","",y,fixed=TRUE))

4
aca

Ich denke, dass die Vorverarbeitung der Weg ist. Sie könnten Notepad ++ verwenden, das eine Option zum Ersetzen eines regulären Ausdrucks hat.

Wenn Ihre Datei beispielsweise so aussieht:

"1,234","123","1,234"
"234","123","1,234"
123,456,789

Dann können Sie den regulären Ausdruck "([0-9]+),([0-9]+)" verwenden und durch \1\2 ersetzen.

1234,"123",1234
"234","123",1234
123,456,789

Dann können Sie x <- read.csv(file="x.csv",header=FALSE) verwenden, um die Datei zu lesen.

2
Jacob

Ein sehr bequemer Weg ist die readr::read_delim-Familie. Nehmen Sie das Beispiel von hier: Importieren von csv mit mehreren Trennzeichen in R Sie können dies wie folgt tun:

txt <- 'OBJECTID,District_N,ZONE_CODE,COUNT,AREA,SUM
1,Bagamoyo,1,"136,227","8,514,187,500.000000000000000","352,678.813105723350000"
2,Bariadi,2,"88,350","5,521,875,000.000000000000000","526,307.288878142830000"
3,Chunya,3,"483,059","30,191,187,500.000000000000000","352,444.699742995200000"'

require(readr)
read_csv(txt) # = read_delim(txt, delim = ",")

Welche Ergebnisse ergeben das erwartete Ergebnis:

# A tibble: 3 × 6
  OBJECTID District_N ZONE_CODE  COUNT        AREA      SUM
     <int>      <chr>     <int>  <dbl>       <dbl>    <dbl>
1        1   Bagamoyo         1 136227  8514187500 352678.8
2        2    Bariadi         2  88350  5521875000 526307.3
3        3     Chunya         3 483059 30191187500 352444.7
1
Rentrop

Mit der Funktion read_delim, die Teil von readr library ist, können Sie zusätzliche Parameter angeben:

locale = locale(decimal_mark = ",")

read_delim("filetoread.csv", ';", locale = locale(decimal_mark = ","))

* Das Semikolon in der zweiten Zeile bedeutet, dass read_delim die durch Semikolon getrennten CSV-Werte liest.

Dies hilft, alle Zahlen mit einem Komma als richtige Zahlen zu lesen.

Grüße

Mateusz Kania

0
Mateusz Kania

Wir können auch readr::parse_number verwenden, die Spalten müssen jedoch Zeichen sein. Wenn wir es auf mehrere Spalten anwenden möchten, können wir mit lapply durch die Spalten schlingen.

df[2:3] <- lapply(df[2:3], readr::parse_number)
df

#  a        b        c
#1 a    12234       12
#2 b      123  1234123
#3 c     1234     1234
#4 d 13456234    15342
#5 e    12312 12334512

Oder verwenden Sie mutate_at aus dplyr, um es auf bestimmte Variablen anzuwenden.

library(dplyr)
df %>% mutate_at(2:3, readr::parse_number)
#Or
df %>% mutate_at(vars(b:c), readr::parse_number)

Daten

df <- data.frame(a = letters[1:5], 
                 b = c("12,234", "123", "1,234", "13,456,234", "123,12"),
                 c = c("12", "1,234,123","1234", "15,342", "123,345,12"), 
                 stringsAsFactors = FALSE)
0
Ronak Shah

Es ist nicht so kompliziert, versuchen Sie Folgendes: Y <- as.numeric (gsub (",", "", as.aracter (y))) kann es mit y $ 2 wie gezeigt unterlegen.

0
Colonelxy

Eine andere Lösung:

 y <- c("1,200","20,000","100","12,111") 

 as.numeric(unlist(lapply( strsplit(y,","),paste, collapse="")))

Es wird jedoch wesentlich langsamer als gsub sein. 

0
liujx80