我想使用lapply对列表元素的子集(字符串)应用正则表达式操作,并返回与原始列表长度相同的列表。列表元素是长字符串(从长文本文件中读取并将段落折叠成单个字符串)。正则表达式操作仅对列表元素/字符串的子集有效。我希望非子集化的列表元素(字符串)以其原始状态返回。
正则表达式操作是来自str_extract
包的stringr
,即我想从更长的字符串中提取子字符串。我根据文件名中的正则表达式模式对列表元素进行了子集化。
简化数据的示例:
library(stringr)
texts <- as.list(c("abcdefghijkl", "mnopqrstuvwxyz", "ghijklmnopqrs", "uvwxyzabcdef"))
filenames <- c("AB1997R.txt", "BG2000S.txt", "MN1999R.txt", "DC1997S.txt")
names(texts) <- filenames
regexp <- "abcdef"
我事先知道我想要应用正则表达式操作的字符串,因此我想要对这些字符串进行子集化。也就是说,我不想对列表中的所有元素运行正则表达式,因为这样做会返回一些无效结果(在此简化示例中不明显)。
我做了一些天真的努力,例如:
x <- lapply(texts[str_detect(names(texts), "1997")], str_extract, regexp)
> x
$AB1997R.txt
[1] "abcdef"
$DC1997S.txt
[1] "abcdef"
返回一个缩小长度的列表,其中只包含找到的子字符串。 但我想得到的结果是:
> x
$AB1997R.txt
[1] "abcdef"
$BG2000S.txt
[1] "mnopqrstuvwxyz"
$MN1999R.txt
[1] "ghijklmnopqrs"
$DC1997S.txt
[1] "abcdef"
其中不包含正则表达式模式的字符串以其原始状态返回。
我已经了解了stringr
,lapply
和llply
(plyr
包中),但许多操作都使用数据框作为示例进行说明,而不是列表,以及不要对字符串进行正则表达式操作。我可以使用for循环来实现我的目标,但是我正试图摆脱它,正如通常所建议的那样,并且在使用apply-class函数时会变得更好。
答案 0 :(得分:4)
您可以使用子集运算符[<-
:
x <- texts
is1997 <- str_detect(names(texts), "1997")
x[is1997] <- lapply(texts[is1997], str_extract, regexp)
x
# $AB1997R.txt
# [1] "abcdef"
#
# $BG2000S.txt
# [1] "mnopqrstuvwxyz"
#
# $MN1999R.txt
# [1] "ghijklmnopqrs"
#
# $DC1997S.txt
# [1] "abcdef"
#
答案 1 :(得分:3)
您可以尝试sub
sub(paste0('.*(', regexp, ').*'), '\\1', texts)
# AB1997R.txt BG2000S.txt MN1999R.txt DC1997S.txt
# "abcdef" "mnopqrstuvwxyz" "ghijklmnopqrs" "abcdef"
此外,如果您需要匹配&#39;文本的名称&#39;使用1997
,我们可以使用grep
indx <- grep('1997', names(texts))
texts[indx] <- sub(paste0('.*(', regexp, ').*'), '\\1', texts[indx])
as.list(texts)