使用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
答案
- 在
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')) - 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替换每个匹配的字符串时,如何简化以下代码?的主要内容,如果未能解决你的问题,请参考以下文章