Appliquer la fonction de chaque colonne d'une trame de données d'observation chacune des colonnes existantes type de données

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

  •  25-10-2019
  •  | 
  •  

Question

Je suis en train d'obtenir le min / max pour chaque colonne dans une grande trame de données, dans le cadre de apprendre à connaître mes données . Mon premier essai était:

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

Il traite tout comme vecteur de caractère, parce que les premières colonnes sont des types de caractères. Donc max de quelques-unes des colonnes numériques sort comme " -99.5".

J'ai ensuite essayé ceci:

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

mais il se plaint de max n'a pas de sens pour les facteurs . (lapply est le même.) Ce qui me est source de confusion que apply de pensée max était parfaitement significative pour les facteurs, par exemple il est revenu "ZEBRA" pour la colonne 1.

BTW, je pris un coup d'œil à aide sapply sur le vecteur de POSIXct et l'une des réponses dit « Lorsque vous utilisez sapply, vos objets sont contraints de numérique, ... ». Est-ce ce qui me passe? Si oui, est-il une alternative fonction qui n'appliquent contraint pas? Certes, il est un besoin commun, comme l'une des principales caractéristiques du type de trame de données est que chaque colonne peut être un type différent.

Était-ce utile?

La solution

Si elle était une des choses « facteur ordonné » seraient différentes. Ce qui ne veut pas dire que je comme « facteurs ordonnés », je ne suis pas, seulement pour dire que certaines relations sont définies pour « ordonné » des facteurs qui ne sont pas définis pour « facteurs ». Les facteurs sont considérés comme des variables ordinaires. Vous voyez l'ordre de tri naturel de facteurs qui est par ordre alphabétique lexical pour vos paramètres régionaux. Si vous voulez obtenir une contrainte automatique « numérique » pour chaque colonne, ... les dates et les facteurs et tout, essayez:

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

Ou si vous voulez tester les facteurs d'abord et retour que vous attendez alors:

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

@Darrens commentaire fonctionne mieux:

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

max ne réussit avec des vecteurs de caractères.

Autres conseils

La raison pour laquelle max travaille avec apply est que apply exerce des pressions sur votre trame de données à une première matrice et une matrice ne peut contenir qu'un seul type de données. Donc, vous vous retrouvez avec une matrice de caractères. sapply est juste une enveloppe pour lapply, il est donc pas surprenant que les deux rendement la même erreur.

Le comportement par défaut lorsque vous créez une trame de données est pour les colonnes catégoriques à être stockés comme facteurs . À moins que vous spécifiez que c'est un commandé facteur, les opérations comme max et min seront non définies, puisque R est en supposant que vous avez créé un non ordonnée facteur.

Vous pouvez modifier ce comportement en spécifiant options(stringsAsFactors = FALSE), qui va changer la valeur par défaut pour toute la session, ou vous pouvez passer stringsAsFactors = FALSE dans la construction de data.frame() appeler lui-même. Notez que ce seulement signifie que min et max assumeront ordre « alphabétique » par défaut.

Vous pouvez également spécifier manuellement une commande pour chaque facteur, même si je doute que ce soit ce que vous voulez faire.

Peu importe, sapply généralement produire un vecteur atomique, ce qui entraînera la conversion tout en caractères dans de nombreux cas. Une façon de contourner cela est la suivante:

#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

Si vous voulez apprendre votre summary (df) de données fournit le min, 1er quantile, médiane et moyenne, 3 quantile et maximum de colonnes numériques et la fréquence des niveaux supérieurs des colonnes de facteur.

la construction sur la réponse de @ ltamar:
Utilisez résumé et munge la sortie en! De quelque chose d'utile

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

Il est pas beau et il est certainement pas rapide mais il fait le travail!

solution A l'aide retype() de hablar à des facteurs de COERCE à caractère ou type numérique en fonction de feasability. J'utilise dplyr pour appliquer max à chaque colonne.

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)

Résultat

Non les nouveaux types de colonnes.

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

Données

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

La meilleure façon de le faire est d'éviter la base absolue * appliquer des fonctions, qui l'ensemble du cadre contraint de données à un tableau, et l'utilisation colwise de plyr . (Je suis surpris que personne n'a mentionné cela)

Exemple d'utilisation parse_guess en fonction agissant sur toutes sortes de types de données vectorielles:

colwise(parse_guess)(t)

Moins réponse intéressante: on peut appliquer sur chaque colonne avec une boucle for:

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

Je ne sais pas d'un bon moyen de faire mission avec * appliquer tout en préservant la structure trame de données .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top