2016-05-19 2 views
1

Ich habe eine data.frame, die Spalten verschiedener Typen enthält, wie z. B. Integer, Zeichen, numerische und Faktor.Eine elegante Möglichkeit zum Ändern von Spalten geben Datenrahmen in R

Ich muss die Integer-Spalten für die Verwendung im nächsten Schritt der Analyse in numerische konvertieren.

Beispiel: test.data enthält 4 Spalten (obwohl es Tausende in meinem realen Datensatz ist): age, gender, work.years und name; age und work.years sind ganze Zahlen, gender ist Faktor, und name ist Zeichen. Was ich tun muss, ist age und work.years in einen numerischen Typ zu ändern. Und ich habe einen Code dafür geschrieben.

test.data[sapply(test.data, is.integer)] <-lapply(test.data[sapply(test.data, is.integer)], as.numeric) 

Es sieht nicht gut genug aus, obwohl es funktioniert. Ich frage mich also, ob es elegantere Methoden gibt, diese Funktion zu erfüllen. Jede kreative Methode wird geschätzt.

+2

Haben Sie andere Arten müssen jeweils zu konvertierenden Klassen ? Ansonsten sieht Ihre Option gut genug aus. Anderen Weg wäre 'test.data [] <- lapply (test.data, Funktion (x) if (is.integer (x)) as.numeric (x) sonst x)' – akrun

+0

@akrun danke für die Antwort zuerst! Nein, in der Situation muss ich nur die Ganzzahl in numerische konvertieren und die anderen Typen ohne Änderung beibehalten. – wanglin

+0

Okay, in diesem Fall wäre entweder Ihr Weg oder der, den ich in den Kommentaren zeigte, gut genug. – akrun

Antwort

11

Ich denke, elegant Code manchmal subjektiv ist. Für mich ist das elegant, aber im Vergleich zum OP-Code möglicherweise weniger effizient. Da es sich jedoch um eleganten Code handelt, kann dieser verwendet werden.

test.data[] <- lapply(test.data, function(x) if(is.integer(x)) as.numeric(x) else x) 

Auch eine andere elegante Möglichkeit ist dplyr

library(dplyr) 
library(magrittr) 
test.data %<>% 
     mutate_each(funs(if(is.integer(.)) as.numeric(.) else .)) 
+3

plus 1 Akrun. Scheint niemand upvotes mehr ... – bgoldst

1

Es sind Aufgaben wie diese, die ich am besten mit expliziten Schleifen erreicht habe. Sie kaufen hier nichts, indem Sie eine einfache For-Schleife durch die versteckte Schleife einer Funktion wie lapply() ersetzen. Beispiel:

## generate data 
set.seed(1L); 
N <- 3L; test.data <- data.frame(age=sample(20:90,N,T),gender=factor(sample(c('M','F'),N,T)),work.years=sample(1:5,N,T),name=sample(letters,N,T),stringsAsFactors=F); 
test.data; 
## age gender work.years name 
## 1 38  F   5 b 
## 2 46  M   4 f 
## 3 60  F   4 e 
str(test.data); 
## 'data.frame': 3 obs. of 4 variables: 
## $ age  : int 38 46 60 
## $ gender : Factor w/ 2 levels "F","M": 1 2 1 
## $ work.years: int 5 4 4 
## $ name  : chr "b" "f" "e" 

## solution 
for (cn in names(test.data)[sapply(test.data,is.integer)]) 
    test.data[[cn]] <- as.double(test.data[[cn]]); 

## result 
test.data; 
## age gender work.years name 
## 1 38  F   5 b 
## 2 46  M   4 f 
## 3 60  F   4 e 
str(test.data); 
## 'data.frame': 3 obs. of 4 variables: 
## $ age  : num 38 46 60 
## $ gender : Factor w/ 2 levels "F","M": 1 2 1 
## $ work.years: num 5 4 4 
## $ name  : chr "b" "f" "e" 
+0

@bgoldst danke! es ist nicht sehr anwendbar für die große Anzahl von Spalten. Die Testdaten, die ich gezeigt habe, sind nur ein Beispiel, um die Frage einfach auszudrücken. Es tut mir leid, dass ich das nicht klar notiert habe. – wanglin

+0

@docendodiscimus @ wanglin Ich hatte ein Missverständnis über die Anforderung. Ich dachte, Sie wollten eine "bekannte" Menge von Spalten von Integer zu Double konvertieren, nicht unbedingt die ganze und exklusive Menge von Spalten, die ganze Zahlen sind. Ich habe gerade meine Lösung bearbeitet, um an der gesamten und exklusiven Menge von Spalten zu arbeiten, die ganze Zahlen sind. Ich glaube das entspricht Ihrer Anforderung. – bgoldst

+1

@bgoldst Danke, Upvoted deins auch. – akrun

4

Jetzt sehr elegant in dplyr (mit magrittr%<>% Operator)

test.data %<>% mutate_if(is.integer,as.numeric)

Verwandte Themen