2013-07-31 14 views
7

Ich brauche Teilmenge Datenrahmen basierend auf Spaltentyp - zum Beispiel aus Datenrahmen mit 100 Spalten Ich muss nur die Spalte mit Typ factor oder integer halten. Ich habe eine kurze Funktion dafür geschrieben, aber gibt es eine einfachere Lösung oder eine eingebaute Funktion oder ein Paket auf CRAN?Subset Variablen im Datenrahmen basierend auf Spaltentyp

Meine aktuelle Lösung Variablennamen mit angeforderten Typen zu bekommen:

varlist <- function(df=NULL, vartypes=NULL) { 
    type_function <- c("is.factor","is.integer","is.numeric","is.character","is.double","is.logical") 
    names(type_function) <- c("factor","integer","numeric","character","double","logical") 
    names(df)[as.logical(sapply(lapply(names(df), function(y) sapply(type_function[names(type_function) %in% vartypes], function(x) do.call(x,list(df[[y]])))),sum))] 
} 

Die Funktion varlist funktioniert wie folgt:

  1. Für jeden gewünschten und für jede Spalte in Datenrahmen Call „ist. TYPE "Funktion
  2. Summe Tests für jede Variable (Boolean wird automatisch in Integer umgewandelt)
  3. Ergebnis auf logischen Vektor umwandeln
  4. Teilmenge Namen in Datenrahmen

Und einige Daten, die es zu testen:

df <- read.table(file="http://archive.ics.uci.edu/ml/machine-learning-databases/statlog/german/german.data", sep=" ", header=FALSE, stringsAsFactors=TRUE) 
names(df) <- c('ca_status','duration','credit_history','purpose','credit_amount','savings', 'present_employment_since','installment_rate_income','status_sex','other_debtors','present_residence_since','property','age','other_installment','housing','existing_credits', 'job','liable_maintenance_people','telephone','foreign_worker','gb') 
df$gb <- ifelse(df$gb == 2, FALSE, TRUE) 
df$property <- as.character(df$property) 
varlist(df, c("integer","logical")) 

Ich frage, weil mein Code wirklich kryptisch und schwer zu verstehen (auch für mich sieht, und ich habe beendete die Funktion vor 10 Minuten).

+1

Ich bin nicht sicher, ich Ihre Frage verstehen, aber warum nicht nur so etwas wie 'df [sapply (df, Funktion (x) is.integer (x) || is.logisch (x))]? – A5C1D2H2I1M1N2O1R2T1

+0

Ich mache diese Art von Subsetting häufig, deshalb habe ich versucht, diese Funktion zu erstellen - um mein Leben zu vereinfachen. –

+2

Btw., Warum müssen Sie dieses ziemlich große data.frame in Ihr reproduzierbares Beispiel herunterladen? Beim nächsten Mal sollten Sie nur einen der integrierten Datensätze verwenden. – Roland

Antwort

2
subset_colclasses <- function(DF, colclasses="numeric") { 
    DF[,sapply(DF, function(vec, test) class(vec) %in% test, test=colclasses)] 
} 

str(subset_colclasses(df, c("factor", "integer"))) 
13

tun Sie einfach das folgende:

df[,sapply(df,is.factor) | sapply(df,is.integer)] 
+0

Wie würde ich etwas wie df [, sapply (df,! is.list)] ???? (bekomme alle Spalten, die NICHT Liste sind) – userJT

+0

@userJT 'df [, sapply (df, Funktion (x)! is.list (x))]' – Thomas

+0

Ich fand auch in der Zwischenzeit heraus, dass dies funktioniert df2 <-df [ ,! sapply (df, is.list)] – userJT

Verwandte Themen