2015-10-16 18 views
31

habe ich eine Probe Datenrahmen wie unten:Coerce mehrere Spalten Faktoren auf einmal

data <- data.frame(matrix(sample(1:40), 4, 10, dimnames = list(1:4, LETTERS[1:10]))) 

Ich möchte wissen, wie kann ich mehrere Spalten und wandeln sie zusammen Faktoren auswählen. Ich mache es normalerweise so wie data$A = as.factor(data$A). Aber wenn der Datenrahmen sehr groß ist und viele Spalten enthält, wird dieser Weg sehr zeitaufwendig sein. Weiß jemand, ob es eine kluge Möglichkeit gibt, es zu tun?

Antwort

48

Wählen Sie einige Spalten Faktoren zu zwingen:

cols <- c("A", "C", "D", "H") 

Verwenden lapply() zu zwingen und die ausgewählten Spalten zu ersetzen:

data[cols] <- lapply(data[cols], factor) 

das Ergebnis überprüfen:

sapply(data, class) 
#  A   B   C   D   E   F   G 
# "factor" "integer" "factor" "factor" "integer" "integer" "integer" 
#  H   I   J 
# "factor" "integer" "integer" 
+0

Müsste es nicht 'data [, Spalten] <- lapply (Daten [, Spalten], Faktor)' sein (mit dem führenden Komma für Spalten)? – Tgsmith61591

+4

@ Tgsmith61591- Es könnte entweder sein. Mit dem Komma ist eine Matrix-Typ-Teilmenge, ohne das Komma ist eine Liste Teilmenge. Datenframes können durch einen der beiden Teilmengen unterteilt werden, so dass jeder Weg funktionieren würde. –

21

Hier ist ein Option mit dplyr. Der Operator %<>% von magrittr aktualisiert das LHS-Objekt mit dem resultierenden Wert.

library(magrittr) 
library(dplyr) 
cols <- c("A", "C", "D", "H") 

data %<>% 
     mutate_each_(funs(factor(.)),cols) 
str(data) 
#'data.frame': 4 obs. of 10 variables: 
# $ A: Factor w/ 4 levels "23","24","26",..: 1 2 3 4 
# $ B: int 15 13 39 16 
# $ C: Factor w/ 4 levels "3","5","18","37": 2 1 3 4 
# $ D: Factor w/ 4 levels "2","6","28","38": 3 1 4 2 
# $ E: int 14 4 22 20 
# $ F: int 7 19 36 27 
# $ G: int 35 40 21 10 
# $ H: Factor w/ 4 levels "11","29","32",..: 1 4 3 2 
# $ I: int 17 1 9 25 
# $ J: int 12 30 8 33 

oder wenn wir data.table verwenden, entweder einen for Schleife mit set

setDT(data) 
for(j in cols){ 
    set(data, i=NULL, j=j, value=factor(data[[j]])) 
} 

oder wir können die 'cols' in .SDcols und weisen (:=) den rhs angeben ' Spalte

setDT(data)[, (cols):= lapply(.SD, factor), .SDcols=cols] 
7

Der jüngere tidyverse Weg, um die mutate_at Funktion zu verwenden ist:

library(tidyverse) 
library(magrittr) 
set.seed(88) 

data <- data.frame(matrix(sample(1:40), 4, 10, dimnames = list(1:4, LETTERS[1:10]))) 
cols <- c("A", "C", "D", "H") 

data %<>% mutate_at(cols, funs(factor(.))) 
str(data) 
$ A: Factor w/ 4 levels "5","17","18",..: 2 1 4 3 
$ B: int 36 35 2 26 
$ C: Factor w/ 4 levels "22","31","32",..: 1 2 4 3 
$ D: Factor w/ 4 levels "1","9","16","39": 3 4 1 2 
$ E: int 3 14 30 38 
$ F: int 27 15 28 37 
$ G: int 19 11 6 21 
$ H: Factor w/ 4 levels "7","12","20",..: 1 3 4 2 
$ I: int 23 24 13 8 
$ J: int 10 25 4 33 
3

und auf Vollständigkeit und in Bezug auf this question asking about changing string columns only, gibt es mutate_if:

data <- cbind(stringVar = sample(c("foo","bar"),10,replace=TRUE), 
       data.frame(matrix(sample(1:40), 10, 10, dimnames = list(1:10, LETTERS[1:10]))),stringsAsFactors=FALSE)  

factoredData = data %>% mutate_if(is.character,funs(factor(.))) 
0

Wenn Sie ein anderes Ziel des Erhaltens in Werten aus die Tabelle dann mit ihnen zu konvertieren, können Sie versuchen, den folgenden Weg

Diese sel ect-Spalten, die speziell zeichenbasiert sind und diese dann in factor umwandeln.