Wenden Sie die Funktion auf jede Spalte in einem Datenrahmen an, in dem die vorhandenen Spalten vorhandenen Datentyp beobachtet wird

StackOverflow https://stackoverflow.com/questions/7303322

  •  25-10-2019
  •  | 
  •  

Frage

Ich versuche, die min/max für jede Spalte in einem großen Datenrahmen als Teil von zu erhalten meine Daten kennenlernen. Mein erster Versuch war:

apply(t,2,max,na.rm=1)

Es behandelt alles als Charaktervektor, da die ersten Spalten Charaktertypen sind. Maxus von einigen der numerischen Spalten kommt also als heraus " -99.5".

Ich habe dann das versucht:

sapply(t,max,na.rm=1)

Aber es beschwert sich darüber maximal nicht sinnvoll für Faktoren. (lapply ist dasselbe.) Was mich verwirrt, ist das apply Gedanke max war für Faktoren perfekt sinnvoll, zB "Zebra" für Spalte 1 zurückgegeben.

Übrigens habe ich einen Blick auf Verwenden von Sapply auf dem Vektor von posixct und eine der Antworten sagt "Wenn Sie Sapply verwenden, werden Ihre Objekte zu numerisch gezwungen, ..." Typ.

War es hilfreich?

Lösung

Wenn es ein "geordneter Faktor" wäre, wären die Dinge anders. Das heißt nicht, dass mir "geordnete Faktoren" gefällt, nur um zu sagen, dass einige Beziehungen für "geordnete Faktoren" definiert sind, die nicht für "Faktoren" definiert sind. Faktoren werden als gewöhnliche kategoriale Variablen angesehen. Sie sehen die natürliche Sortierreihenfolge von Faktoren, die alphabetische lexikalische Ordnung für Ihr Gebietsschema sind. Wenn Sie für jede Spalte einen automatischen Zwang für "numerisch" erhalten möchten, ... Daten und Faktoren und alles, versuchen Sie es mit:

sapply(df, function(x) max(as.numeric(x)) )   # not generally a useful result

Oder wenn Sie zuerst auf Faktoren testen und wie Sie erwarten, dann: dann:

sapply( df, function(x) if("factor" %in% class(x) ) { 
            max(as.numeric(as.character(x)))
            } else { max(x) } )

@Darrens Kommentar funktioniert besser:

 sapply(df, function(x) max(as.character(x)) )  

max erfolgreich mit Charaktervektoren.

Andere Tipps

Der Grund dass max arbeitet mit apply ist das apply zwingt Ihren Datenrahmen zuerst zu einer Matrix, und eine Matrix kann nur einen Datentyp enthalten. Sie haben also eine Matrix von Zeichen. sapply ist nur eine Wrapper für lapply, Es ist also nicht verwunderlich, dass beide den gleichen Fehler ergeben.

Das Standardverhalten, wenn Sie einen Datenrahmen erstellen Faktoren. Es sei denn, Sie geben an, dass es ein ist bestellt Faktor, Operationen wie max und min wird undefiniert sein, da R angenommen wird, dass Sie eine erstellt haben ungeordnet Faktor.

Sie können dieses Verhalten ändern, indem Sie angeben options(stringsAsFactors = FALSE), die den Standard für die gesamte Sitzung ändern oder Sie übergeben können stringsAsFactors = FALSE in dem data.frame() Konstruktion rufen sich an. Beachten Sie, dass dies nur bedeutet min und max wird standardmäßig "alphabetische" Bestellung annehmen.

Oder Sie können eine Bestellung für jeden Faktor manuell angeben, obwohl ich bezweifle, dass Sie das tun möchten.

Trotzdem, sapply wird im Allgemeinen einen Atomvektor ergeben, der in vielen Fällen alles um die Umwandlung in Charaktere beinhaltet. Ein Weg um diese ist wie folgt:

#Some test data
d <- data.frame(v1 = runif(10), v2 = letters[1:10], 
                v3 = rnorm(10), v4 = LETTERS[1:10],stringsAsFactors = TRUE)

d[4,] <- NA

#Similar function to DWin's answer          
fun <- function(x){
    if(is.numeric(x)){max(x,na.rm = 1)}
    else{max(as.character(x),na.rm=1)}
}   

#Use colwise from plyr package
colwise(fun)(d)
         v1 v2       v3 v4
1 0.8478983  j 1.999435  J

Wenn Sie Ihre Daten lernen möchten summary (df) liefert die min, 1. quantile, median und mittlere, 3. quantil und max der numerischen Säulen und die Häufigkeit der oberen Ebenen der Faktorspalten.

Aufbau auf @ltamars Antwort:
Verwenden Sie die Zusammenfassung und töten Sie die Ausgabe in etwas Nützliches!

library(tidyr)
library(dplyr)

df %>% 
  summary %>% 
  data.frame %>%
  select(-Var1) %>%
  separate(data=.,col=Freq,into = c('metric','value'),sep = ':') %>%
  rename(column_name=Var2) %>%
  mutate(value=as.numeric(value),
         metric = trimws(metric,'both') 
  ) %>%  
  filter(!is.na(value)) -> metrics

Es ist nicht schön und es ist sicherlich nicht schnell, aber es erledigt die Arbeit!

Eine Lösung mit retype() Von Habl bis zu Koisfaktoren bis hin zu Charakter oder numerischen Typ abhängig von der Durchführbarkeit. Ich würde benutzen dplyr zum Anwenden maximal auf jede Spalte.

Code

library(dplyr)
library(hablar)

# Retype() simplifies each columns type, e.g. always removes factors
d <- d %>% retype()

# Check max for each column
d %>% summarise_all(max)

Ergebnis

Nicht die neuen Spaltentypen.

     v1 v2       v3 v4   
  <dbl> <chr> <dbl> <chr>
1 0.974 j      1.09 J   

Daten

# Sample data borrowed from @joran
d <- data.frame(v1 = runif(10), v2 = letters[1:10], 
                v3 = rnorm(10), v4 = LETTERS[1:10],stringsAsFactors = TRUE)

Der absolut beste Weg, dies zu tun, besteht darin colwise aus PLYR. (Ich bin überrascht, dass niemand das erwähnt hat)

Beispiel verwenden parse_guess Als eine Funktion, die auf allen Arten von Vektordatenatypen arbeitet:

colwise(parse_guess)(t)

Weniger interessante Antwort: Wir können uns auf jede Spalte mit einem For-Loop bewerben:

for (i in 1:nrow(t)) { t[, i] <- parse_guess(t[, i]) }

Ich weiß nicht eine gute Art von Zuordnung mit *anwenden während der Aufrechterhaltung der Datenrahmenstruktur.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top