根据另一列的字符串内容创建新列

时间:2020-06-24 12:29:29

标签: r regex dataframe

我有以下数据:

gene_Id <- c( 'No_id' , 'P1_1_EXN' , 'P1_2_EXN' , 
              'P1_1_EXN_O' , 'P1_2_EXN_O' ,
              'P2_1_EXN' , 'P2_2_EXN' , 
              'P2_1_EXN_O' , 'P2_2_EXN_O' , 
             'P1nM1'  , 'P2nM1')

Count_F <- c(rep('KL',5),rep('KD',6))

DF <- data.frame(gene_Id , Count_F)

我想创建另外三列: first_one 应该替换具有模式的单元格 '_Number_'与 例如'gene_'Number' 更换 P1_1_EXNgene_1一起使用,可以控制不符合此条件的其余字符串的名称。还可以在模式'_Number_'之后提取字符串的其余部分,例如: 在上一个示例中仅使用EXN​,并将其放在 second_one 中。

third_one 应该将任何具有'P Number'的单元格替换为 例如,'PREP Number'P1_1_EXN替换PREP _1

编辑:这是预期的输出。

PRER <- c ( 'No_P' ,rep('PREP_1' , 4) , rep('PREP_2' , 4) , 'PREP_1' , 'PREP_2')

Gene_Num <- c ('No_num' , 'gene_1' , 'gene_2' , 'gene_1' , 'gene_2' ,'gene_1',
               'gene_2', 'gene_1', 'gene_2'  , 'NEG' , 'NEG')

Rest <-c('No_rest','EXN','EXN','EXN_O','EXN_O','EXN','EXN','EXN_O','EXN_O', 'Neg','Neg')


New_DF <- cbind(DF,Gene_Num,Rest,PRER)

非常感谢。

2 个答案:

答案 0 :(得分:2)

这是使用dplyr软件包和case_when的一种可能性。

DF %>%
  mutate(col1 = case_when(grepl("_\\d_", gene_Id) ~ gsub(".*_(\\d)_.*", "gene_\\1", gene_Id),
                          TRUE ~ "dummy1"),
         col2 = case_when(grepl("_\\d_", gene_Id) ~ gsub("^.*_\\d_", "", gene_Id),
                          TRUE ~ "dummy2"),
         col3 = case_when(grepl("P\\d", gene_Id) ~ gsub(".*P(\\d).*", "PREP_\\1", gene_Id),
                          TRUE ~ "dummmy3"))

      gene_Id Count_F   col1   col2    col3
1       No_id      KL dummy1 dummy2 dummmy3
2    P1_1_EXN      KL gene_1    EXN  PREP_1
3    P1_2_EXN      KL gene_2    EXN  PREP_1
4  P1_1_EXN_O      KL gene_1  EXN_O  PREP_1
5  P1_2_EXN_O      KL gene_2  EXN_O  PREP_1
6    P2_1_EXN      KD gene_1    EXN  PREP_2
7    P2_2_EXN      KD gene_2    EXN  PREP_2
8  P2_1_EXN_O      KD gene_1  EXN_O  PREP_2
9  P2_2_EXN_O      KD gene_2  EXN_O  PREP_2
10      P1nM1      KD dummy1 dummy2  PREP_1
11      P2nM1      KD dummy1 dummy2  PREP_2

以下是一些解释: 首先,我使用grepl检查gene_ID中是否包含所需的子字符串。如果是,我将根据规则将其提取。如果没有,我将分配一个虚拟值(我将其命名为dummy1,dummy2和dummy3)。

我使用正则表达式匹配字符串:\\d匹配一个数字,而_\\d_匹配两个下划线之间的数字。 使用gsub时,\\1指的是第一个括号中匹配的内容:在这种情况下,它始终是数字。

例如,col1的定义如下:

  1. 检查是否在_\\d_内找到模式gene_ID:如果是,将整个字符串替换为gene_\\1,其中\\1是下划线之间的数字。
  2. 如果找不到模式_\\d_,请分配“ dummy1”。

答案 1 :(得分:2)

使用dplyrstringr的替代方法:

DF %>%
  mutate(Gene     = str_c("gene", str_extract(gene_Id, "_\\d(?=_)")),
         Rest     = str_extract(gene_Id, "(?<=_\\d_).*"),
         P_Number = str_replace(str_extract(gene_Id, "P\\d"), "P", "PREP_"))

返回

      gene_Id Count_F   Gene  Rest P_Number
1       No_id      KL   <NA>  <NA>     <NA>
2    P1_1_EXN      KL gene_1   EXN   PREP_1
3    P1_2_EXN      KL gene_2   EXN   PREP_1
4  P1_1_EXN_O      KL gene_1 EXN_O   PREP_1
5  P1_2_EXN_O      KL gene_2 EXN_O   PREP_1
6    P2_1_EXN      KD gene_1   EXN   PREP_2
7    P2_2_EXN      KD gene_2   EXN   PREP_2
8  P2_1_EXN_O      KD gene_1 EXN_O   PREP_2
9  P2_2_EXN_O      KD gene_2 EXN_O   PREP_2
10      P1nM1      KD   <NA>  <NA>   PREP_1
11      P2nM1      KD   <NA>  <NA>   PREP_2

我没有提供<NA>案例的句柄。