2016-06-26 5 views
0

データで再生していて、辞書でもよいキーと値のペアを含む新しいデータフレームを作成しようとしていました。サンプルデータと簡単なマニュアルソリューションがあります。キーと値のペアを持つ辞書として機能する新しいデータフレームを作成する

df = data.frame(col1 = c("one", "one", "two", "two", "one"), 
       col2 = c("AG", "AB", "AC", "AG", "AB"), 
       col3 = c("F3", "F1", "F2", "F3", "F2")) 
df 
d1 = data.frame(vals = unique(df$col1)) 
d2 = data.frame(vals = unique(df$col2)) 
d3 = data.frame(vals = unique(df$col3)) 
d1 
d2 
d3 
d1$name = "col1" 
d2$name = "col2" 
d3$name = "col3" 
d1 
d2 
d3 
rbind(d1,d2,d3) 

もちろん、これは簡単な使用例であり、実際のデータはもっと平凡なものになるでしょう。そのため、私は辞書を通ってキーの値のペアを設定できるループを探していました。

ほとんどの試みは失敗に終わりました。ここで私のソリューションのフォーマットはありますが、new_df辞書を動的に作成する方法がわかりません。助言がありますか?

new_df=data.frame() 
prod.cols = c("col1", "col2", "col3") 
for(col in prod.cols){ 
    if(col %in% colnames(df)){ 
    ## solution in here 
    } 
} 

new_df 
+1

'ユニーク行うことができます(data.frame(名=名(DF)、ヴァルスを=のC(T(DF)))) ' – rawr

答えて

4

tidyrこれは簡単です:

library(tidyr) 

df %>% gather(name, vals) %>% unique() 

# name vals 
# 1 col1 one 
# 3 col1 two 
# 6 col2 AG 
# 7 col2 AB 
# 8 col2 AC 
# 11 col3 F3 
# 12 col3 F1 
# 13 col3 F2 
4

alistaireの答えは非常にエレガントで読みやすいです。ちょうど楽しみのために、ここに基本的なRのアプローチがあります。その効率は特に重要ではありませんが、これは多くの行と列が追加されるので、比較的よくうまくいきます:

私の2番目と3番目のアプローチは私の最初のアプローチよりも良いので、答えの先頭に移動します:

アプローチ#2、素敵な、効率的なワンライナー用thelatemailさんのコメントを実装:

stack(lapply(df, function(ii) as.character(unique(ii)))) 

何このソリューションについての素晴らしいのは、それが最初as.characterのための少ない作業を行いuniqueを、使用して列を低減し、その後のためということですstack


アプローチ#3:係数列に対処するlevelsを使用してuniqueと文字変換の必要性を回避するアプローチ2のより簡潔かつより効率的なバージョン:

stack(lapply(df, levels)) 

ファーストアプローチ:

Reduce(rbind, 
    lapply(seq_along(df), 
     function(ii) data.frame(vals = unique(df[, ii]), name = names(df)[ii]) 
    ) 
) 

# vals name 
#1 one col1 
#2 two col1 
#3 AG col2 
#4 AB col2 
#5 AC col2 
#6 F3 col3 
#7 F1 col3 
#8 F2 col3 

do.callReduceのnsteadは、ここではほぼ同じです:

do.call(rbind, 
    lapply(seq_along(df), 
     function(ii) data.frame(vals = unique(df[, ii]), name = names(df)[ii]) 
    ) 
) 
+2

私には' stack'操作のように見えます - 'unique(stack(lapply(df、as.character)))' – thelatemail

+0

@thelatemail yea、そうです。私は 'stack'を使ってみましたが、文字変換のステップがありませんでした。私は 'unique 'を呼び出す前に大きな構造体を作るのを避けるためにこの変更が好きです:' stack(lapply(df、function(ii)as.character(unique(ii))) ')。かなり効率的でなければならない。答えを加えたいですか? – Jota

+1

あなたの変更は非常に巧妙です。好きなだけ編集しても構いません。 – thelatemail

1

我々も

library(reshape2) 
unique(melt(as.matrix(df))[-1]) 
+1

あなたは 'id'引数を使って次のように保存することができます。しかし、それは無関係です;) 'unique(reshape2 :: melt(df、id = 0))' – user20650

関連する問題