创建(mutate)列,条件是另一个

时间:2017-07-22 02:33:17

标签: r conditional-statements create-table mutate mutated

我有这个数据

     COL
    AABC1
   AAAABD2
  AAAAAABF3

我想制作一个像这样的专栏:

     COL         NEW_COL
    AABC1          T1
   AAAABD2         T2
  AAAAAABF3        T3

如果COL包含'BC',则NEW_COL将为T1

包含'BD',它将是T2

包含'BF',它将是T3。

我想使用mutate和grepl函数,但我有80个条件(如BC> T1),因此代码在R中不起作用。

使用如下表格:

    CLASS       NEW_COL
    BC          T1
    BD          T2
    BF          T3

我可以使用带有上述标准表的mutate(create)新列吗?

2 个答案:

答案 0 :(得分:2)

这是您的数据:

DF <- data.frame(COL = c("AABC1",
                         "AAAABD2",
                         "AAAAABF3"), 
                 stringsAsFactors = FALSE)

lookup_tbl <- data.frame(CLASS = c("BC", "BD", "BF"),
                         NEW_COL = c("T1", "T2", "T3"), 
                         stringsAsFactors = FALSE)

在初步准备之后,通过加入解决了您的问题。

要准备DF,您需要添加一列,从CLASS中的COL中提取查找表中DF的任何实例。然后你可以正常加入。在R:

library(dplyr)
DF %>%
  mutate(CLASS = gsub(paste0("^.*(", 
                            paste0(lookup_tbl[["CLASS"]], collapse = "|"),
                            ").*$"), 
                      "\\1",
                      lookup_tbl[["CLASS"]])) %>%
  # or inner_join as required
  left_join(lookup_tbl, by = "CLASS")

解决方案的行为COL如何与CLASS中的一个或多个实例匹配将需要指定。以上处理这两种情况,但可能不是你想要的。

答案 1 :(得分:0)

您可以使用80个条件创建一个查找表,并编写一个与其匹配的小函数。这是一个示例(通常,您在lookup_table中从文件中读取,我在猜测):

library(tidyverse)

lookup_table <- data.frame(
                    row.names = c('BC', 'BD', 'BF'), 
                    new_col = c('T1', 'T2', 'T3'), 
                    stringsAsFactors = FALSE)

lookup <- function(x, table) {
    for (class in rownames(table)) {
        if (grepl(class, x)) {
            return(table[class, 'new_col'])
        }
    }
}

data_frame(col = c('AABC1', 'AAAABD2', 'AAAAAABF3')) %>% 
    rowwise %>% mutate(new_col = lookup(col, lookup_table))

请注意,这将采用它找到的第一个匹配项,因此请确保您的查找表已根据您要提供匹配规则的优先级进行了正确排序。