2015-11-06 12 views
5

Sto provando a utilizzare lapply in un elenco di frame di dati; ma fallendo nel passare correttamente i parametri (credo).Utilizzo di lapply per modificare i nomi delle colonne di un elenco di frame di dati

Elenco dei frame di dati:

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 

vettore con i nomi di colonne:

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

mi piacerebbe cambiare i nomi delle colonne utilizzando lapply:

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

ma questo doesn cambiare i nomi. Non sto passando i frame di dati stessi, ma qualcos'altro? Voglio solo cambiare i nomi, non restituire il risultato a un nuovo oggetto.

Grazie in anticipo, p.

+0

non avrebbe funzionato a causa della chiamata * R per valore * – jogo

+1

Basta aggiungere un 'x' alla fine' lapply (listDF, la funzione (x) {colnames (x) [2: lunghezza (x)] < -todos [1: length (x) -1]; x}) '. La tua funzione come scritta non ha valore di ritorno. –

+1

Non correlato alla domanda, ma suppongo che '1: length (x) -1' sia un errore comune (a volte non dannoso). La linea destra è '1: (length (x) -1)' (fai attenzione alla precedenza!) – nicola

risposta

11

È inoltre possibile utilizzare setNames se si desidera sostituire tutte le colonne

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 

Se è necessario sostituire solo un sottoinsieme di nomi di colonna, allora si può utilizzare la soluzione di @Jogo

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

un ultimo punto, in R c'è una differenza tra un: b - 1 e (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

Se si desidera modificare i nomi delle colonne del data.frame in ambiente globale da un elenco, è possibile utilizzare list2env ma non sono sicuro che sia il modo migliore per raggiungere vuole si volere. È inoltre necessario modificare l'elenco e utilizzare l'elenco con nome, il nome deve corrispondere al nome dello data.frame che è necessario sostituire.

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

Controllare l'uscita rispetto al codice dell'OP. La riga 'colnames (x) [2: length (x)]' indica che la sostituzione inizia dalla seconda colonna. –

+0

@PierreLafortune Grazie Pierre hai ragione, ho apportato qualche modifica – dickoa

+0

Scusa dickoa ma lapply cambia solo i nomi delle colonne * all'interno * dell'elenco (quindi df1 e df2 hanno ancora i nomi dei colli originali !!). Ho anche provato ad aggiungere la "x" di Pierre, ma ancora non lo fa. Io uso solo la lista per contenere un lungo elenco di DF, non che voglio cambiamenti all'interno della lista stessa. Qualche idea? grazie – user3310782

1

provare questo:

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

si otterrà una nuova lista con dataframes modificati. Se si vuole manipolare la listDF direttamente:

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

Grazie jogo ma perché non cambia i nomi delle colonne del frame di dati? Cambia solo i nomi delle colonne all'interno dell'elenco, non nel DF indipendente. – user3310782

+0

ma si può fare 'listDF <- lapply (...)' – jogo

+0

Certo, ma se si desidera modificare i nomi delle colonne DF, allora lapply NON è la strada da percorrere? – user3310782