1

我有这个数据

     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) new 列吗?

4

2 回答 2

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,您需要添加一列,从in中提取CLASS查找表中的任何实例。然后就可以正常加入了。在 R 中:COLDF

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以上处理了这两种情况,但可能不是你想要的。

于 2017-07-22T05:45:23.837 回答
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))

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

于 2017-07-22T03:48:20.973 回答