【问题标题】:Replace multiple values in data table column after multiple pattern match多个模式匹配后替换数据表列中的多个值
【发布时间】:2021-03-05 06:09:40
【问题描述】:

这是一个可以帮助像我这样的一些“R初学者”的sn-p: 我指的是这个线程需要我的 melted 数据表:

Replace entire string anywhere in dataframe based on partial match with dplyr

我正在寻找一种简单的方法,用部分匹配字符串替换数据表中的一个列中的整个字符串。我在论坛上找不到合适的人选,因此发了这篇文章。

dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3")
> dt
      x    y    z
1:  A_1  K_1  P_1
2: BB_2 LL_2 QQ_2
3: CC_3 MM_3 RR_3

用多个模式替换 col y 中的多个值以匹配:

dt[,2]<-str_replace_all(as.matrix(dt[,2]),c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR"))

在列上使用as.matrix() 会排除str_replace_all() 函数的输入警告。 结果是:

> dt[,2]<-str_replace_all(as.matrix(dt[,2]),c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR"))
> dt
      x       y    z
1:  A_1 FORMULA  P_1
2: BB_2    RACE QQ_2
3: CC_3     CAR RR_3
>

非常不优雅,但对我有用,当列数据很大时,这似乎是一个快速的解决方案。

需要library(stringr)。 感谢您提出任何改进建议。

在我尝试以下方法时编辑这篇文章:

dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3"))            
dt[, nu_col := c(1:3)]
molten.dt<-melt(dt,id.vars = "nu_col", measure.vars = c("x","y","z"))
molten.dt[, one_more := ifelse(grepl("A_.*", value), "HONDA","FERRARI")]

我在 Rstudio 的控制台上看到的错误是:

Error in `:=`(one_more, ifelse(grepl("A_.*", value), "HONDA", "FERRARI")) : 
  Check that is.data.table(DT) == TRUE. Otherwise, := and `:=`(...) are defined for use in j, once only and in particular ways. See help(":=").

在 R 终端上运行得非常好

> dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_$
> dt[, nu_col := c(1:3)]
> molten.dt<-melt(dt,id.vars = "nu_col", measure.vars = c("x","y","z"))
> molten.dt
   nu_col variable value
1:      1        x   A_1
2:      2        x  BB_2
3:      3        x  CC_3
4:      1        y   K_1
5:      2        y  LL_2
6:      3        y  MM_3
7:      1        z   P_1
8:      2        z  QQ_2
9:      3        z  RR_3
> molten.dt[, one_more := ifelse(grepl("A_.*", value), "HONDA","FERRARI")]
> molten.dt
   nu_col variable value one_more
1:      1        x   A_1    HONDA
2:      2        x  BB_2  FERRARI
3:      3        x  CC_3  FERRARI
4:      1        y   K_1  FERRARI
5:      2        y  LL_2  FERRARI
6:      3        y  MM_3  FERRARI
7:      1        z   P_1  FERRARI
8:      2        z  QQ_2  FERRARI
9:      3        z  RR_3  FERRARI
>

【问题讨论】:

    标签: r string design-patterns replace data.table


    【解决方案1】:

    有不同的 API 用于更新。虽然这是:

    tib <- tib %>% mutate(new_col = old_col + 2)
    

    使用:= 运算符就地完成同样的事情:

    dt[, new_col := old_col + 2]
    

    所以请注意,一旦我们在括号内,我们就可以将向量传递给其他函数。要将其应用于您的示例,我们可以这样做...

    library(data.table)
    library(stringr)
    dt<-data.table(x=c("A_1", "BB_2", "CC_3"),y=c("K_1", "LL_2", "MM_3"),z=c("P_1","QQ_2","RR_3"))            
    
    dt[, y := str_replace_all(y,c("K_.*" = "FORMULA","LL_.*" = "RACE","MM_.*" = "CAR")) ]               
    
    dt
    
    ##         x       y      z
    ##    <char>  <char> <char>
    ## 1:    A_1 FORMULA    P_1
    ## 2:   BB_2    RACE   QQ_2
    ## 3:   CC_3     CAR   RR_3
    

    注意,由于str_replace_all 需要一个向量,您可以将as.matrix(dt[,2]) 替换为dt[[2]]。不同之处在于dt[, 2] 生成单列data.table; as.matrix(dt[, 2]) 产生一个单列矩阵,而dt[[2]] 产生一个向量。我仍然建议使用dt[, new := old + 2] 类型的语法。

    【讨论】:

    • 早上好!谢谢,我总是更喜欢将函数用于 data.table 的 j 参数。您的回答消除了对单列使用与向量使用以及非常流行的:= 使用的混淆。我偶然发现了字符向量和:= 用于j 的其他几个问题。
    • 这是我在 RStuido 的控制台中以 RScript 形式运行 foll.code 时遇到的情况:我编辑了我的原始帖子,如果这篇帖子有更多噪音,敬请见谅
    • 我唯一的想法是你已经加载了reshape2。因此,您实际上调用的是reshape2::melt`()``. I was able to reproduce the error when I explicitly called reshape2::melt()```,而不是data.table::melt()。请注意,编辑更像是一个新问题。
    • 是的,我认为这是一个新问题。我想用建议的试用来结束这篇文章。在脚本中没有明确说明,但是在 RStudio 环境中,reshape 已加载。在 R 终端环境中也不会“看到”吗?为了简单起见,在环境中我同时加载了 data.table 和 reshape2,并且我假设 Rterminal 和控制台在通过 Rstudio 访问时具有相同的环境。我可能是错的。
    • 再讲一个.. 我通读了melt()documentation,并假设在 R 终端和控制台中,melt() 的工作方式相同。
    猜你喜欢
    • 2021-11-17
    • 1970-01-01
    • 2012-09-28
    • 2016-04-24
    • 2015-10-23
    • 1970-01-01
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    相关资源
    最近更新 更多