2015-11-06 15 views
5

Próbuję użyć lapply na liście ramek danych; ale nie udało się poprawnie przekazać parametrów (chyba).Używanie lapply do zmiany nazw kolumn listy ramek danych

Lista ramek danych:

df1 <- data.frame(A = 1:10, B= 11:20) 
df2 <- data.frame(A = 21:30, B = 31:40) 

listDF <- list(df1, df2,df3) #multiple data frames w. way less columns than the length of vector todos 

Vector z kolumn nazwami:

todos <-c('col1','col2', ......'colN') 

Chciałbym zmienić nazwy kolumn za pomocą lapply:

lapply (listDF, function(x) { colnames(x)[2:length(x)] <-todos[1:length(x)-1] } ) 

ale to nie robi w ogóle nie zmieniają imion. Czy nie przekazuję samych ramek danych, ale coś innego? Chcę tylko zmienić nazwy, aby nie zwracać wyniku do nowego obiektu.

Z góry dziękuję, str.

+0

nie działa z powodu wywoływania * r poprzez wartość * – jogo

+1

Wystarczy dodać 'x' do końca' lapply (listDF funkcja (x) {colnames (x) [2: długość (x)] < -todos [1: length (x) -1]; x}) '. Twoja funkcja jako zapisana nie ma wartości zwracanej. –

+1

Nie związane z pytaniem, ale myślę, że '1: length (x) -1' jest częstym błędem (czasem nie jest szkodliwy). Właściwa linia to '1: (długość (x) -1)' (uważaj na pierwszeństwo!) – nicola

Odpowiedz

11

Można również użyć setNames jeśli chcesz zastąpić wszystkie kolumny

df1 <- data.frame(A = 1:10, B= 11:20) 
df2 <- data.frame(A = 21:30, B = 31:40) 

listDF <- list(df1, df2) 
new_col_name <- c("C", "D") 

lapply(listDF, setNames, nm = new_col_name) 
## [[1]] 
##  C D 
## 1 1 11 
## 2 2 12 
## 3 3 13 
## 4 4 14 
## 5 5 15 
## 6 6 16 
## 7 7 17 
## 8 8 18 
## 9 9 19 
## 10 10 20 

## [[2]] 
##  C D 
## 1 21 31 
## 2 22 32 
## 3 23 33 
## 4 24 34 
## 5 25 35 
## 6 26 36 
## 7 27 37 
## 8 28 38 
## 9 29 39 
## 10 30 40 

jeśli trzeba wymienić tylko część nazwy kolumn, a następnie można użyć roztworu @Jogo

lapply(listDF, function(df) { 
    names(df)[-1] <- new_col_name[-ncol(df)] 
    df 
}) 

ostatnim punkcie, R jest różnica między b - 1, oraz (b - 1)

1:10 - 1 
## [1] 0 1 2 3 4 5 6 7 8 9 

1:(10 - 1) 
## [1] 1 2 3 4 5 6 7 8 9 

EDIT

Jeśli chcesz zmienić nazwy kolumn z data.frame w globalnym środowisku z listy, można użyć list2env ale nie jestem pewien, że to jest najlepszy sposób na osiągnięcie żebyś chcieć. Musisz również zmodyfikować listę i użyć nazwanej listy, nazwa powinna być taka sama jak nazwa data.frame, którą musisz zastąpić.

listDF <- list(df1 = df1, df2 = df2) 

new_col_name <- c("C", "D") 

listDF <- lapply(listDF, function(df) { 
    names(df)[-1] <- new_col_name[-ncol(df)] 
    df 
}) 

list2env(listDF, envir = .GlobalEnv) 
str(df1) 
## 'data.frame': 10 obs. of 2 variables: 
## $ A: int 1 2 3 4 5 6 7 8 9 10 
## $ C: int 11 12 13 14 15 16 17 18 19 20 
+0

Sprawdź wyjście i kod OP. Wiersz 'colnames (x) [2: length (x)]' wskazuje, że zamiennik zaczyna się od drugiej kolumny. –

+0

@PierreLafortune Dzięki Pierre masz rację, dokonałem korekty – dickoa

+0

Niestety dickoa ale lapply zmienia tylko nazwy kolumn * wewnątrz * listy (więc df1 i df2 nadal mają oryginalne nazwy kolumn !!). Próbowałem też dodać "x" od Pierre'a, ale nadal to nie działa. Używam tylko tej listy do przechowywania długiej listy plików DF, a nie, że chcę zmiany na samej liście. Jakieś pomysły? dzięki – user3310782

1

spróbuj tego:

lapply (listDF, function(x) { 
    names(x)[-1] <- todos[-length(x)] 
    x 
}) 

dostaniesz nową listę zmienionych dataframes. Jeśli chcesz manipulować listDF bezpośrednio:

for (i in 1:length(listDF)) names(listDF[[i]])[-1] <- todos[-length(listDF[[i]])] 
+0

Dzięki jogo, ale dlaczego nie zmienia nazwy kolumn w ramce danych? Zmienia tylko nazwy kolumn na liście, a nie w niezależnym pliku DF. – user3310782

+0

ale możesz zrobić 'listDF <- lapply (...)' – jogo

+0

Oczywiście, ale jeśli chcesz zmienić nazwy kolumn DF, to czy nie jest to droga do zrobienia? – user3310782

Powiązane problemy