2016-12-04 12 views
2

私は特別な方法で結合しようとしている2つのテーブルを持っています。一つは、それが関連付けられているHEXの色とそのカテゴリを提供する単純なtibbleです:条件に基づいてあるテーブルから別のテーブルに値を追加する

library(tibble) 
library(dplyr) 

colors <- tibble(Category = c("A", "B", "C", "D"), 
        Colors = c("#0079c0", "#cc9900", "#252525", "#c5120e")) 

# A tibble: 4 × 2 
    Category Colours 
    <chr> <chr> 
1  A #0079c0 
2  B #cc9900 
3  C#252525 
4  D #c5120e 

私は、行と列とカテゴリの両方を示しています別のtibbleがあり、それらは特定の方法で表示されます。

Main_Table <- tibble(Category = c("A", "B", "C", "D"), 
        A = c(NA, "A", NA, NA), 
        B = c(NA, NA, NA, NA), 
        C = c(NA, "C", NA, NA), 
        D = c("D", "D", NA, NA)) 

# A tibble: 4 × 5 
    Category  A  B  C  D 
    <chr> <chr> <lgl> <chr> <chr> 
1  A <NA> NA <NA>  D 
2  B  A NA  C  D 
3  C <NA> NA <NA> <NA> 
4  D <NA> NA <NA> <NA> 

対応するカテゴリがその名前を保持する変数の下に存在するかどうかに基づいて、メインテーブルに色を追加したいとします。たとえば、のは、私は、カテゴリD'sの色が含まれるようにしたい場合は、私は以下で終わるだろうと言ってみましょう:

Main_Table_Goal <- tibble(Category = c("A", "B", "C", "D"), 
        A = c(NA, "A", NA, NA), 
        B = c(NA, NA, NA, NA), 
        C = c(NA, "C", NA, NA), 
        D = c("D", "D", NA, NA), 
        color = c("#c5120e", "#c5120e", NA, NA)) 

# A tibble: 4 × 6 
    Category  A  B  C  D color 
     <chr> <chr> <lgl> <chr> <chr> <chr> 
1  A <NA> NA <NA>  D #c5120e 
2  B  A NA  C  D #c5120e 
3  C <NA> NA <NA> <NA>  <NA> 
4  D <NA> NA <NA> <NA>  <NA> 

どのように私はdplyrを使ってこれを実現するのですか?私は*_joinと他のトリックで試してきましたが、私はどこにもいませんでした。

編集:私は最終的にこれを関数に含めることを言及しておきたいので、理想的には任意の数のカテゴリに対応するためにコードを柔軟にすることができます。

答えて

3

ここではmatch

Main_Table %>% 
     mutate(color = colors$Colors[match(D, colors$Category)]) 
# A tibble: 4 × 6 
# Category  A  B  C  D color 
#  <chr> <chr> <lgl> <chr> <chr> <chr> 
#1  A <NA> NA <NA>  D #c5120e 
#2  B  A NA  C  D #c5120e 
#3  C <NA> NA <NA> <NA> <NA> 
#4  D <NA> NA <NA> <NA> <NA> 
を使用してオプションです。
+1

私はちょうど 'match'で遊んでいました。 – jazzurro

+1

'match'関数はまさに私を逃していたものです...ありがとう! – Phil

+1

このマッチのアイデアを考えると、 'mutate_at(vars(A:D)、funs(color = Colors [match(。、Category)]))は私の考えを改訂する方法ですね。 – jazzurro

2

あなたのデータにいくつのカテゴリがあるのか​​わかりません。ただし、4つしかない場合(A、B、C、D)は、次のような方法があります。私は1つのデータフレームで作業したかったのです。だから私は最初に2つのデータフレームをマージしました。私はmutate_at()を使いたかったので、Bを論理的に文字に変換しました。次に、4つのカテゴリを4つの色に置き換えました。最後に、Colorsを削除し、Bを論理値に変換しました。

library(dplyr) 

left_join(Main_Table, colors) %>% 
mutate(B = as.character(B)) %>% 
mutate_at(vars(A:D), 
      funs(color = recode(., A = Colors[1], 
           B = Colors[2], 
           C = Colors[3], 
           D = Colors[4]))) %>% 
select(-Colors) %>% 
mutate(B = as.logical(B)) 

akrunの考えを踏まえて、以下を行うことができます。あなたが持っているカテゴリの数を知ることができれば、列をvars()に指定するだけです。すべての列が文字であれば、論理を文字に変換する必要はありません。

left_join(Main_Table, colors) %>% 
mutate(B = as.character(B)) %>% 
mutate_at(vars(A:D),funs(color = Colors[match(., Category)])) %>% 
select(-Colors) %>% 
mutate(B = as.logical(B)) 


# Category  A  B  C  D A_color B_color C_color D_color 
#  <chr> <chr> <lgl> <chr> <chr> <chr> <chr> <chr> <chr> 
#1  A <NA> NA <NA>  D <NA> <NA> <NA> #c5120e 
#2  B  A NA  C  D #0079c0 <NA> #252525 #c5120e 
#3  C <NA> NA <NA> <NA> <NA> <NA> <NA> <NA> 
#4  D <NA> NA <NA> <NA> <NA> <NA> <NA> <NA> 
+0

ありがとうございます。私はこれが実際には関数の一部であり、最終的にはこれを動的に実行したいので、カテゴリの数が変わる可能性があると言いました。 – Phil

+1

に更新が好きです。 Plus one(以前のもの) – akrun

1

これは、あなたが一番上に一度色パラメータを設定する動的なソリューションです:

target_category <- 'D' # set color 
target_category_table <- Main_Table %>% 
    select_(target_category) %>% 
    left_join(colors %>% 
        filter(Category == target_category) %>% 
        setNames(c(target_category, 'color'))) 
goal_table <- Main_Table %>% 
    bind_cols(select(target_category_table, color)) 
goal_table 

結果:

# A tibble: 4 × 6 
    Category  A  B  C  D color 
    <chr> <chr> <lgl> <chr> <chr> <chr> 
1  A <NA> NA <NA>  D #c5120e 
2  B  A NA  C  D #c5120e 
3  C <NA> NA <NA> <NA> <NA> 
4  D <NA> NA <NA> <NA> <NA> 
+0

私のベーコンを保存したばかりかもしれません。ありがとうございます。 :) – Phil

+0

@Philようこそ。 'target_category_table'と' goal_table'は、このシナリオ以外のシナリオでは正しくアライメントされないので、バインドするときは注意してください。おそらく両方のテーブルに 'Category'変数を保持し、' bind_cols'を使うのではなく、それに参加するべきです。あなたがそれに応じてソリューションを編集したいかどうかを教えてください。 –

関連する問題