2016-12-04 88 views
2

我有两个表,我试图以特定方式加入。一个是简单的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的颜色,我想最终在下面:

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

'匹配'功能正是我想不到的......谢谢! – Phil

+1

鉴于这种匹配思想,mutate_at(vars(A:D),funs(color = Colors [match(。,Category)]))'是修改我的想法的方法,不是吗? – jazzurro

2

我不确定您的数据中有多少类别。但是如果你只有四个(即A,B,C和D),以下将是单向的。我想使用一个数据框。所以我最初合并了两个数据框。由于我想使用mutate_at(),所以我将B逻辑转换为字符。然后,我用四种颜色替换了四个类别。最后,我删除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

曾经喜欢你的更新。加一(前面给出) – 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'。如果您希望我相应地编辑解决方案,请告知我。 –

相关问题