在列表元素的子集上使用lapply并返回与R

时间:2015-05-31 20:03:25

标签: regex r plyr lapply

我想使用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"

其中不包含正则表达式模式的字符串以其原始状态返回。

我已经了解了stringrlapplyllplyplyr包中),但许多操作都使用数据框作为示例进行说明,而不是列表,以及不要对字符串进行正则表达式操作。我可以使用for循环来实现我的目标,但是我正试图摆脱它,正如通常所建议的那样,并且在使用apply-class函数时会变得更好。

2 个答案:

答案 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)