2015-11-06 105 views
5

我試圖在數據幀列表上使用lapply;但未能正確傳遞參數(我認爲)。使用lapply更改數據幀列表的列名稱

數據幀列表:

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 

向量與列名:

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

我想用lapply改列名:

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

,但是這並未根本不會改變名字。我不是自己傳遞數據框架,而是其他的東西?我只想更改名稱,而不是將結果返回給新對象。

在此先感謝,p。

+0

不會因爲由值* R的呼叫的工作* – jogo

+1

只需添加一個'x'到端'lapply(listDF,函數(X){colnames(x)的[2:長度(X)] < -todos [1:length(x)-1]; x})'。你寫的函數沒有返回值。 –

+1

與問題無關,但我想'1:length(x)-1'是一個常見的錯誤(有時不是有害的)。右邊的行是'1:(length(x)-1)'(小心優先!) – nicola

回答

11

您也可以使用setNames如果要更換所有列

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 

如果您需要更換僅列名的一個子集,那麼你就可以使用@Jogo

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

最後一個點的溶液中,R中有一個之間的差:乙 - 1和:(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 

編輯

如果你想從列表中的全球環境改變data.frame的列名,你可以使用list2env但我不知道它是實現想讓你的最佳途徑想。您還需要修改列表並使用命名列表,該名稱應與您需要替換的data.frame的名稱相同。

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

檢查輸出與OP的代碼。 'colnames(x)[2:length(x)]'這一行表示替換從第二列開始。 –

+0

@PierreLafortune感謝皮埃爾你是對的,我做了一些調整 – dickoa

+0

對不起dickoa,但lapply只改變列表中的列名*(因此df1和df2仍然有原始列名!!)。我也嘗試添加皮埃爾的'x',但仍然沒有辦法。 我只使用列表來保存DF的長列表,而不是我想要在列表本身內進行更改。有任何想法嗎?謝謝 – user3310782

1

試試這個:

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

您將獲得與改變dataframes一個新的列表。如果您想直接操縱listDF

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

謝謝jogo,但爲什麼它不改變數據框的列名?它只改變列表中的列名,而不是在獨立的DF中。 – user3310782

+0

但你可以做'listDF < - lapply(...)' – jogo

+0

當然,但是如果你想改變DF列名,那麼lapply不是要走的路嗎? – user3310782

相關問題