Wenden Sie die Funktion auf jede Spalte in einem Datenrahmen an, in dem die vorhandenen Spalten vorhandenen Datentyp beobachtet wird
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.
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.