我的答案如下,但请考虑改用@user20650 的答案。它更加简洁和优雅(尽管如果您不熟悉正则表达式可能难以理解)。根据@user20650 的第二条评论,请检查以确保它足够强大以处理您的实际数据。
这是一个tidyverse 选项:
library(tidyverse)
vec = c("this example sentence I have given here",
"and here is another long example")
vec.abbrev = vec %>%
map_chr(~ str_split(.x, pattern=" ", simplify=TRUE) %>%
gsub("(.{5}).*", "\\1.", .) %>%
paste(., collapse=" "))
vec.abbrev
[1] "this examp. sente. I have given. here"
[2] "and here is anoth. long examp."
在上面的代码中,我们使用map_chr 来迭代vec 中的每个句子。管道 (%>%) 将每个函数的结果传递给下一个函数。
句点字符可能会造成混淆,因为它具有多个含义,具体取决于上下文。"(.{5}).*" 是Regular Expression,其中. 表示“匹配任何字符”。在"\\1." 中,. 实际上是一个句点。 gsub("(.{5}).*", "\\1.", .) 中的最后一个 . 和 paste(., collapse=" ") 中的第一个 . 是一个“代词”,表示我们传递给当前函数的前一个函数的输出。
这是一步一步的过程:
# Split each string into component words and return as a list
vec.abbrev = str_split(vec, pattern=" ", simplify=FALSE)
# For each sentence, remove all letters after the fifth letter in
# a word and replace with a period
vec.abbrev = map(vec.abbrev, ~ gsub("(.{5}).*", "\\1.", .x))
# For each sentence, paste the component words back together again,
# each separated by a space, and return the result as a vector,
# rather than a list
vec.abbrev = map_chr(vec.abbrev, ~paste(.x, collapse=" "))