改变与定义的字符串匹配的新列

时间:2017-08-16 19:03:17

标签: r string pattern-matching dplyr grepl

我想mutate数据框的一列,具体取决于匹配的特定条件。我看了四周但到目前为止还找不到一些简洁的解决方案。 use-mutate-to-create-new-column-label-with-conditions

所以这是我使用的简单数据框

gr = rep(seq(1,2),each=3)
clas=c("A_1","A_2","A_3","A_4","A_5","A_6")

df <- data.frame(gr,clas)

> df
  gr clas
1  1  A_1
2  1  A_2
3  1  A_3
4  2  A_4
5  2  A_5
6  2  A_6

我想A_4,A_5和A_6与B_1,B_2和B_3

所以我试过

match <- paste('_',seq(4,6),sep='')
 df%>%
  mutate(clas=ifelse(clas %in% match,paste('B',seq(1,3),sep='_'),clas))

       gr clas
    1  1    1
    2  1    2
    3  1    3
    4  2    4
    5  2    5
    6  2    6

和第二次尝试使用grepl

df%>%
mutate(clas=ifelse(clas==grepl(paste(match,collapse='|'),clas),paste('B',seq(1,3),sep='_'),clas))

   gr clas
1  1    1
2  1    2
3  1    3
4  2    4
5  2    5
6  2    6

A&A已经消失了:)预期的结果是;

   gr clas
1  1  A_1
2  1  A_2
3  1  A_3
4  2  B_1
5  2  B_2
6  2  B_3

谢谢!

编辑:我意识到如果数据clas列中有LETTERS,则更容易做到。但是,如果我们有这样的数据而没有gr列,那我们怎么做?

    clas
1   CD_1
2  X.2_2
3  K$2_3
4 12k3_4
5   .A_5
6   xy_6

预期输出

    clas
1   CD_1
2  X.2_2
3  K$2_3
4 12kB_4
5   .B_5
6   xB_6

我想我正在寻找像那样的解决方案

3 个答案:

答案 0 :(得分:1)

这是一个依赖df$gr的基础R解决方案:

paste(LETTERS[df$gr], ave(df$gr, df$gr, FUN=seq_along), sep="_")
[1] "A_1" "A_2" "A_3" "B_1" "B_2" "B_3

LETTERS是拉丁文大写字母,LETTERS[1]是&#34; A&#34;。所以&#34; A&#34;和&#34; B&#34;被粘贴到由seq_along构建的运行计数的结果,该结果使用ave按组重置。这两个用&#34; _&#34;粘贴在一起。作为分隔符。

答案 1 :(得分:1)

以下是dplyr解决方案:

df%>%group_by(gr)%>%dplyr::mutate(clas=paste0(toupper(letters[gr]),"_",row_number()))
#you can change toupper(letters[gr]) to LETTERS[gr]

# A tibble: 6 x 2
# Groups:   gr [2]
     gr  clas
  <int> <chr>
1     1   A_1
2     1   A_2
3     1   A_3
4     2   B_1
5     2   B_2
6     2   B_3

答案 2 :(得分:1)

我将尝试使用base R:专门用于解决此问题:

首先确保你的矢量是字符形式。我打电话给B

上面的表格
  B[,1]=as.character(B[,1])
  B[4:6,1]=sapply(B$clas[4:6],function(i) {substr(i,nchar(i)-2,nchar(i)-2)<-"B";i})
  B
     clas
 1   CD_1
 2  X.2_2
 3  K$2_3
 4 12kB_4
 5   .B_5
 6   xB_6