在列表元素的子集上使用 lapply 和与 R 中原始长度相同的 return 列表
Use lapply on a subset of list elements and return list of same length as original in R
我想使用 lapply 和 return 与原始长度相同的列表,将正则表达式操作应用于列表元素的子集(字符串)。列表元素是长字符串(源自读取长文本文件并将段落折叠成单个字符串)。正则表达式操作仅对列表 elements/strings 的子集有效。我希望将非子集列表元素(字符串)return编辑为原始状态。
正则表达式操作是 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"
我事先知道要对哪些字符串应用正则表达式操作,因此我想对这些字符串进行子集化。也就是说,我不想 运行 列表中所有元素的正则表达式,因为这样做会 return 一些无效结果(这在这个简化的示例中并不明显)。
我做了一些幼稚的努力,例如:
x <- lapply(texts[str_detect(names(texts), "1997")], str_extract, regexp)
> x
$AB1997R.txt
[1] "abcdef"
$DC1997S.txt
[1] "abcdef"
其中 return 是一个缩减长度的列表,仅包含找到的子字符串。
但是我想要得到的结果是:
> x
$AB1997R.txt
[1] "abcdef"
$BG2000S.txt
[1] "mnopqrstuvwxyz"
$MN1999R.txt
[1] "ghijklmnopqrs"
$DC1997S.txt
[1] "abcdef"
其中不包含正则表达式模式的字符串 return 以其原始状态编辑。
我已经了解了 stringr
、lapply
和 llply
(在 plyr
包中),但是许多操作都是使用数据框作为示例进行说明的,而不是列表,并且不涉及对字符串的正则表达式操作。我可以使用 for 循环实现我的目标,但我正在尝试摆脱它,正如通常建议的那样,并更好地使用函数的 apply-class 。
您可以使用子集运算符 [<-
:
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"
#
你可以试试sub
sub(paste0('.*(', regexp, ').*'), '\1', texts)
# AB1997R.txt BG2000S.txt MN1999R.txt DC1997S.txt
# "abcdef" "mnopqrstuvwxyz" "ghijklmnopqrs" "abcdef"
此外,如果您需要将 'texts' 的名称与 1997
匹配,我们可以使用 grep
indx <- grep('1997', names(texts))
texts[indx] <- sub(paste0('.*(', regexp, ').*'), '\1', texts[indx])
as.list(texts)
我想使用 lapply 和 return 与原始长度相同的列表,将正则表达式操作应用于列表元素的子集(字符串)。列表元素是长字符串(源自读取长文本文件并将段落折叠成单个字符串)。正则表达式操作仅对列表 elements/strings 的子集有效。我希望将非子集列表元素(字符串)return编辑为原始状态。
正则表达式操作是 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"
我事先知道要对哪些字符串应用正则表达式操作,因此我想对这些字符串进行子集化。也就是说,我不想 运行 列表中所有元素的正则表达式,因为这样做会 return 一些无效结果(这在这个简化的示例中并不明显)。
我做了一些幼稚的努力,例如:
x <- lapply(texts[str_detect(names(texts), "1997")], str_extract, regexp)
> x
$AB1997R.txt
[1] "abcdef"
$DC1997S.txt
[1] "abcdef"
其中 return 是一个缩减长度的列表,仅包含找到的子字符串。 但是我想要得到的结果是:
> x
$AB1997R.txt
[1] "abcdef"
$BG2000S.txt
[1] "mnopqrstuvwxyz"
$MN1999R.txt
[1] "ghijklmnopqrs"
$DC1997S.txt
[1] "abcdef"
其中不包含正则表达式模式的字符串 return 以其原始状态编辑。
我已经了解了 stringr
、lapply
和 llply
(在 plyr
包中),但是许多操作都是使用数据框作为示例进行说明的,而不是列表,并且不涉及对字符串的正则表达式操作。我可以使用 for 循环实现我的目标,但我正在尝试摆脱它,正如通常建议的那样,并更好地使用函数的 apply-class 。
您可以使用子集运算符 [<-
:
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"
#
你可以试试sub
sub(paste0('.*(', regexp, ').*'), '\1', texts)
# AB1997R.txt BG2000S.txt MN1999R.txt DC1997S.txt
# "abcdef" "mnopqrstuvwxyz" "ghijklmnopqrs" "abcdef"
此外,如果您需要将 'texts' 的名称与 1997
匹配,我们可以使用 grep
indx <- grep('1997', names(texts))
texts[indx] <- sub(paste0('.*(', regexp, ').*'), '\1', texts[indx])
as.list(texts)