2012-04-15 26 views
7

私は、列名の一部が大文字で、一部が小文字であることを除いて、同じ列見出しを持つデータフレームのセットを持っています。すべての列名を小文字に変換して、すべてのものの1つの大きなデータフレームを作成したいと思います。複数のデータフレームで列名を小文字に設定するにはどうすればよいですか?

私は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<-" 

私は小文字の列名を持っているすべての私のデータフレームを変更するにはどうすればよいですか?

答えて

8

次の作業をする必要があります。このような

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

の問題は、一般的には単一のデータ構造にすべてのデータフレームを配置していないし、その後のように、厄介なものを使用することを余儀なくされているという事実に由来しますget

わけではありません、それは私のコードでは、私が実際に最初のデータフレームの単一のリストを作成し、そのCOLNAMESを変更するlapplygetを使用しています。

あなたのlowercols関数は、むしろun-Rのようなものです。 R関数は一般に、何も返さないが副作用があるような方法で呼び出されることはありません。そのような(可能な)関数を書くことを試みると、おそらくあなたの人生は困難になり、スコープの問題があります。私の2番目のlapplyでは、変更されたデータフレームを明示的に返すことに注意してください。

+0

なぜデータフレーム自体のリストを作成できなかったのですか?もちろん、それはより良い解決策です。私はそれを試してみる機会があるとすぐに答えを受け入れるでしょう。 –

+0

それは完璧に動作し、リストとしてデータフレームを持っているので、すべての別々のデータフレームを1つの大きなdfにすることは 'data <-ldply(dfList、rbind.fill)'と同じくらい簡単でした。ありがとうと私はとても感謝しています建設的で有用なコミュニティがここにあります。 –

+0

'lapply(dfs、get)は本当に必要ですか? data.framesのリストを提供するだけでは十分ではないでしょうか? –

4

@ジョランの答えは、スタイルと "あなたはおそらくこれを別にしたい"というメッセージの両方で大きく重なっています。しかし、「男に魚を与えて、あなたは彼を一日食べ、彼に鋭い棒をつけて、目で殴ることができる」という精神で...

あなたが望むことをする機能があります私は完全を期すため、ここでplyr::renameが含ま

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

ものの、:

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 
} 

ここでは小文字の列名と結果を返す2つの代替機能は次のとおりです(と思う)あなたがそれをしたいが、その方法で、この場合、実際にはそれは価値があるよりもトラブルです。

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人に鋭い棒を与えるために+1。 –

+0

私がやりたいと思ったことをどうやってやるのかを明確にしてくれてありがとう。私は 'assign()'の 'sys.frame(-2)'が何をしているのか分かりませんが、それはおそらく私がすべてをうまく割り当てることを理解していないからでしょう。 –

1

これはあなたの質問に直接答えませんが、解決しようとしている問題を解決する可能性があります。

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

2つ以上のdfsを扱う場合、マージは答えではありませんが、ヒントのおかげです。彼らは将来的に便利になるだろうと確信しています。 –

+0

@WilliamGunn: "私はそれらをマージできるように、すべての列名を小文字に変換したいと思っています。私は、data.framesをマージするために列名を変更する必要がないことを指摘していました。おそらくあなたは/ rbindを追加することを意味するときにマージを使用しましたか? –

+0

私はあなたが何と答えているのかを理解しました。どのように私は単語のマージを使用するのか分かりませんでしたが、特にデータフレームのペアでのみ動作する 'merge()'を使用することを意味しませんでした。私はそれを変更します。 –

関連する問題