2015-06-04 10 views
6

Mam następujący data.frame:Jak wymienić data.frame nazwy kolumn sznurkiem w odpowiedniej tabeli przeglądowej w R

set.seed(126) 
df <- data.frame(a=sample(c(1:100, NA), 10), b=sample(1:100, 10), c=sample(1:100, 10), d = c(1:10)) 
    a b c d 
1 18 27 53 1 
2 44 16 66 2 
3 58 47 3 3 
... 

i następującą tabelą przeglądową:

varnames <- data.frame(old = c("a", "b", "c"), new = c("dog", "cat", "mouse")) 
    old new 
1 a dog 
2 b cat 
3 c mouse 

Co Ja zamiast tego próbujesz zastąpić names(df) odpowiednim ... Jeśli names(df) nie jest w varnames$old, zachowaj nazwę kolumny w df ...

Powstały data.frame Chciałbym wrócił wyglądałby następująco:

dog cat mouse d 
1 57 10 83 1 
2 53 99 94 2 
3 99 60 39 3 
... 

Wszelka pomoc mile widziana.

Odpowiedz

9

Jak o użyciu match() funkcję

mm <- match(names(df), varnames$old) 
names(df)[!is.na(mm)] <- as.character(varnames$new[na.omit(mm)]) 
head(df) 
# dog cat mouse d 
# 1 65 48 19 1 
# 2 46 15 80 2 
# 3 NA 47 84 3 
# 4 68 34 46 4 
# 5 23 75 42 5 
# 6 92 87 68 6 

Jeśli jesteś zainteresowany, można również użyć

library(dplyr) 
df %>% rename_(.dots=with(varnames, setNames(as.list(as.character(old)), new))) 

Albo jeszcze jedna opcja funkcję dplyrrename() pakiet data.table ma setnames funkcję

library(data.table) 
setnames(df, as.character(varnames$old), as.character(varnames$new)) 
+1

Myślę, że w przypadku, gdy 'varnames' nigdy nie ma nazw kolumn, które nie są obecne w' df' (tak jak zakładałeś w implementacji 'setnames', w przeciwnym razie to nie zadziała), możesz uprościć swoje pierwsze dwa linie do samych nazw (df) [dopasowanie (varnames $ old, names (df))] <- as.character (varnames $ new) '. Niezła implementacja 'setnames' btw. –

+0

@DavidArenburg w rzeczywistości 'data.table' wersja' setnames' nie zakłada, że ​​wszystkie wartości są obecne w wektorze zastępczym. Wszystkie powyższe metody powinny być równoważne, jak napisane. – MrFlick

+0

Co mam na myśli to, że jeśli zmienisz 'varnames', aby wypowiedzić' varnames <- data.frame (stare = c ("l", "b", "c"), nowe = c ("pies", " cat "," mouse "))', twoje podstawowe podejście R nadal będzie działało zgodnie z oczekiwaniami, a 'setnames' zawiedzie. –

2

Jeszcze jedna opcja jest mapvalues() z pakietu plyr:

library(plyr) 
names(df) <- mapvalues(names(df), 
          from = varnames$old, 
          to = as.character(varnames$new)) 

Jeśli używasz pakietu dplyr, można nazwać to z plyr::mapvalues() więc nie trzeba ładować plyr na szczycie dplyr (co powoduje problemy).