使用grepl替换每个匹配的字符串时,如何简化以下代码?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用grepl替换每个匹配的字符串时,如何简化以下代码?相关的知识,希望对你有一定的参考价值。

我列出的文件名(data $ name)列如下:

aaa.doc
aaa.pptx
http://aaa
aaa.jpg
guide
some memo
...

我希望尽可能用所有类型替换它们,没有特定文件类型的名称我只会将其标记为“其他”。

用文件类型替换文件名列时,我这样做了:

data$name[grepl("http",data$name,ignore.case = FALSE)]<-"web"
data$name[grepl("pptx",data$name,ignore.case = FALSE)]<-"ppt"
data$name[grepl("pdf",data$name,ignore.case = FALSE)]<-"pdf"
data$name[grepl("txt",data$name,ignore.case = FALSE)]<-"txt"
...

1.如何简化这个还是有更好的方法吗?

2.如何替换与我列出的任何类型都不匹配的文件名?

例如:当文件名是指南时,我会用“其他”替换它。

谢谢。


请看我的问题:

> d <- structure(list(name = structure(c(1L, 3L, 5L, 2L, 4L, 7L, 6L), .Label = c("aaa.doc", "aaa.jpg", "aaa.pptx", "guide", "http://aaa", "memo", "some"), class = "factor")), class = "data.frame",row.names = c(NA, -7L))
> d
        name
1    aaa.doc
2   aaa.pptx
3 http://aaa
4    aaa.jpg
5      guide
6       some
7       memo
> trans <- c(http = "web", pptx = "ppt", pdf = "pdf", txt = "txt")
> pat <- paste(names(trans), collapse = "|")  # http|pptx|pdf|txt
> strapply(as.character(d$name), pat, ~ trans[x], empty = "others", simplify = TRUE)
[[1]]
NULL

[[2]]
[1] "pptx"

[[3]]
[1] "http"

[[4]]
NULL

[[5]]
NULL

[[6]]
NULL

[[7]]
NULL
答案
  1. tidyverse方式,它可能看起来像下面。您可以为case_when()添加更多选项 库(tidyverse) data < - tibble(name = c('aaa.doc','aaa.pptx','aaa.txt','aaa.pdf','http:////aaa','aaa.jpg','guide','一些备忘录“)) data < - data%>%mutate(name = case_when(str_detect(tolower(name),“http”)〜“web”,str_detect(tolower(name),“pptx”)〜“ppt”,str_detect(tolower(name) ),“pdf”)〜“pdf”,str_detect(tolower(name),“txt”)〜“txt”,str_detect(tolower(name),“guide”)〜“other”,TRUE~'unknown'))
  2. TRUE应该是最后一行来处理所有其他情况。
另一答案

1)strapply定义一个命名向量trans,将匹配转换为类型。然后找到trans名称并使用strapply翻译每个名称。

strapply的第一个参数是输入字符向量,第二个是要匹配的模式,第三个是应用于此处使用公式表示法表示的匹配的函数,empty参数指定在没有匹配时使用的内容和simplify=TRUE原因它输出一个普通的字符向量而不是列表。

library(gsubfn)

trans <- c(http = "web", pptx = "ppt", pdf = "pdf", txt = "txt")

pat <- paste(names(trans), collapse = "|")  # http|pptx|pdf|txt
strapply(tolower(d$name), pat, ~ trans[x], empty = "others", simplify = TRUE)
## [1] "others" "ppt"    "web"    "others" "others" "others" "others"

2)Base R使用上面的trans我们可以创建一个简单的循环。

result <- result.ini <- tolower(d$name)
for(nm in names(trans)) result[ grepl(nm, result) ] <- trans[nm]
result[ result == result.ini ] <- "others"
result
## [1] "others" "ppt"    "web"    "others" "others" "others" "others"

3)R Base - Reduce我们可以使用Reduce,其方式与for循环基本相同,但没有显式循环:

Match <- function(result, nm) ifelse(grepl(nm, result), trans[nm], result)
out <- Reduce(Match, names(trans), init = tolower(d$name))
out[out == tolower(d$name)] <- "others"
out
## [1] "others" "ppt"    "web"    "others" "others" "others" "others"

注意

可重复输入的输入:

d <- 
structure(list(name = structure(c(1L, 3L, 5L, 2L, 4L, 7L, 6L), .Label = c("aaa.doc", 
"aaa.jpg", "aaa.pptx", "guide", "http://aaa", "memo", "some"), 
class = "factor")), class = "data.frame", row.names = c(NA, -7L))

以上是关于使用grepl替换每个匹配的字符串时,如何简化以下代码?的主要内容,如果未能解决你的问题,请参考以下文章

使用 grepl 在 R 中获取匹配的字符串

R语言grep函数和grepl函数字符匹配实战

R语言——字符串处理

C#Regex使用匹配值替换

R语言学习14-stringr包

我们如何在匹配两个文本文件时查找和替换单词?