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

时间:2019-04-20 08:56:03

标签: r

我的文件名(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

2 个答案:

答案 0 :(得分:1)

  1. tidyverse的形式如下所示。您可以向case_when()

    添加更多选项

    图书馆(tidyverse)

    数据<-tibble(name = c('aaa.doc','aaa.pptx','aaa.txt','aaa.pdf',                       'http:////aaa','aaa.jpg','指南','一些备忘录'))

    数据<-数据%>%   mutate(名称= 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 :(得分:1)

1)定义一个命名向量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)基数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基-减少我们可以以与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))