2012-04-15 68 views
7

我有一組具有相同列標題的數據框,除了一些列名是大寫的,有些是小寫的。我想將所有的列名轉換爲小寫,這樣我就可以創建一個大的數據框。如何爲多個數據框設置列名爲小寫?

我似乎無法讓colnames()工作在任何循環或應用我寫。 有了:

#create dfs 
df1<-data.frame("A" = 1:10, "B" = 2:11) 
df2<-data.frame("a" = 3:12, "b" = 4:13) 
df3<-data.frame("a" = 5:14, "b" = 6:15) 
#I have many more dfs in my actual data 

#make list of dfs, define lowercasing function, apply across df list 
dfs<-ls(pattern = "df") 
lowercols<-function(df){colnames(get(df))<-tolower(colnames(get(df)))} 
lapply(dfs, lowercols) 

我得到以下錯誤:

Error in colnames(get(df)) <- tolower(colnames(get(df))) : 
    could not find function "get<-" 

如何改變我所有的dataframes有小寫列名?

回答

8

下面應該工作:

dfList <- lapply(lapply(dfs,get),function(x) {colnames(x) <- tolower(colnames(x));x}) 

這樣的問題一般的事實,你沒有放置在一個單獨的數據結構中的所有數據幀,然後被迫使用一些尷尬,比如干get

這並不是說在我的代碼,我使用lapplyget實際創建的數據幀第一的一個列表,然後改變其colnames。

你也應該知道你的lowercols函數是相當不像R的。 R函數通常不會以什麼不返回的方式調用,但會產生副作用。如果你試圖用這種方式來編寫函數(這是可能的),你可能會讓你的生活變得困難並且有確定範圍的問題。請注意,在我的第二個lapply中,我顯式返回修改後的數據幀。

+0

爲什麼我沒有想到自己創建數據框的列表?當然這是更好的解決方案。只要有機會嘗試一下,我會盡快接受答案。 – 2012-04-15 23:46:06

+0

完美地工作,然後將數據框作爲列表,將所有單獨的數據幀合併到一個大的df中,就像'data <-ldply(dfList,rbind.fill)一樣簡單''謝謝,我非常感謝這裏有建設性的和有幫助的社區。 – 2012-04-16 02:18:25

+0

'lapply(dfs,get)'真的有必要嗎?簡單地提供data.frames列表是不夠的? – 2016-08-04 18:12:31

4

@ joran的回答與我的風格重疊,無論是在風格上還是在「你可能想要做不同的事情」的信息中。然而,本着「給一個人一條魚,你喂他一天,給他一個尖銳的棍子,並且他可以在自己的眼睛裏捅自己」的精神......

這裏有一個功能,可以做你想做的在(你認爲)你想要的方式做到這一點:

dfnames <- ls(pattern = "df[0-9]+") ## avoid 'dfnames' itself 
lowercolnames <- function(df) { 
    x <- get(df) 
    colnames(x) <- tolower(colnames(x)) 
    ## normally I would use parent.frame(), but here we 
    ## have to go back TWO frames if this is used within lapply() 
    assign(df,x,sys.frame(-2)) 
    ## OR (maybe simpler) 
    ## assign(df,x,envir=.GlobalEnv) 

    NULL 
} 

下面是小寫的列名,並返回結果兩個備用功能:

lowerCN2 <- function(x) { 
    colnames(x) <- tolower(colnames(x)) 
    x 
} 

我包括plyr::rename這裏的完整性,雖然在這種情況下,它實際上比它的價值更麻煩。

lowerCN3 <- function(x) { 
    plyr::rename(x,structure(tolower(colnames(x)), 
          names=colnames(x))) 
} 

dflist <- lapply(dfnames,get) 
dflist <- lapply(dflist,lowerCN2) 
dflist <- lapply(dflist,lowerCN3) 
+0

+1給男人一個尖銳的棍子。 – 2012-04-16 01:13:36

+0

感謝您的明確代碼,告訴我我將如何做我認爲我想做的事。我不明白'assign()'中的'sys.frame(-2)'是做什麼的,但這可能是因爲我不明白把所有這些都分配好了。 – 2012-04-16 02:23:36

1

這並不直接回答你的問題,但它可能會解決你正在嘗試解決的問題;你可以通過不同的名稱合併data.frames,例如:

df1 <- data.frame("A" = 1:10, "B" = 2:11, x=letters[1:10]) 
df2 <- data.frame("a" = 3:12, "b" = 4:13, y=LETTERS[1:10]) 
merge(df1, df2, by.x=c("A","B"), by.y=c("a","b"), all=TRUE) 
+0

有兩個以上的dfs需要處理,合併不是答案,但謝謝你的提示。我相信他們會在未來派上用場。 – 2012-04-16 02:26:20

+0

@WilliamGunn:您說過,「我想將所有列名轉換爲小寫,以便我可以合併它們。」我只是指出,您不必更改列名以合併data.frames。也許你使用合併時,你的意思是append/rbind? – 2012-04-16 04:44:09

+0

我明白你在回答什麼,謝謝!我混淆瞭如何使用合併這個詞,但並不是特意使用'merge()',它只適用於成對的數據框。我會改變這一點。 – 2012-04-16 19:03:13

相關問題