studio - sostituire valori in r




Applicare la funzione a ciascuna colonna in un frame di dati osservando ogni tipo di dati esistente di colonne (3)

Sto cercando di ottenere il minimo / massimo per ogni colonna in una grande cornice di dati, come parte della conoscenza dei miei dati . Il mio primo tentativo è stato:

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

Tratta tutto come un vettore di caratteri, perché le prime colonne sono tipi di caratteri. Quindi il massimo di alcune delle colonne numeriche sta uscendo come " -99.5" .

Ho quindi provato questo:

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

ma si lamenta del massimo non significativo per i fattori . ( lapply è la stessa cosa.) Ciò che mi confonde è che apply pensiero max era perfettamente significativo per i fattori, ad esempio restituiva "ZEBRA" per la colonna 1.

A proposito, ho dato un'occhiata a Using sapply sul vettore di POSIXct e una delle risposte dice " Quando usi sapientamente, i tuoi oggetti sono forzati in caratteri numerici, ... ". È questo che mi sta succedendo? In tal caso, esiste un'alternativa che applica la funzione che non costringe? Sicuramente è una necessità comune, poiché una delle caratteristiche chiave del tipo di frame di dati è che ogni colonna può essere di un tipo diverso.


Il motivo per cui max funziona con apply è che apply sta forzando prima il frame di dati su una matrice, e una matrice può contenere solo un tipo di dati. Quindi finisci con una matrice di personaggi. sapply è solo un wrapper per lapply , quindi non è sorprendente che entrambi lapply lo stesso errore.

Il comportamento predefinito quando si crea un frame dati è per le colonne categoriali da memorizzare come fattori . A meno che non si specifichi che si tratta di un fattore ordinato , le operazioni come max e min non saranno definite, poiché R sta presupponendo di aver creato un fattore non ordinato .

È possibile modificare questo comportamento specificando le options(stringsAsFactors = FALSE) , che cambierà il valore predefinito per l'intera sessione oppure è possibile passare stringsAsFactors = FALSE nella chiamata di costruzione data.frame() stessa. Nota che questo significa che min e max assumeranno l'ordine "alfabetico" di default.

Oppure puoi specificare manualmente un ordine per ogni fattore, anche se dubito che sia quello che vuoi fare.

Indipendentemente da ciò, generalmente saprà produrre un vettore atomico, che implicherà la conversione di tutto in caratteri in molti casi. Un modo per aggirare questo è il seguente:

#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

Se fosse un "fattore ordinato" le cose sarebbero diverse. Il che non vuol dire che mi piacciono i "fattori ordinati", io no, solo per dire che alcune relazioni sono definite per "fattori ordinati" che non sono definiti per "fattori". I fattori sono considerati variabili ordinarie categoriali. Stai vedendo l'ordinamento naturale dei fattori che è l'ordine lessicale alfabetico per la tua localizzazione. Se vuoi ottenere una coercizione automatica su "numerico" per ogni colonna, ... date e fattori e tutto, quindi prova:

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

O se vuoi testare prima i fattori e tornare come ti aspetti:

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

Il commento di @Darrens funziona meglio:

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

max riesce con i vettori di caratteri.


basandosi sulla risposta di @ ltamar:
Usa il riepilogo e munge l'output in qualcosa di 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

Non è bello e non è certamente veloce ma ha il compito!





sapply