Я предполагаю, что вы хотите перебрать элементы spamdata
и создать индикатор того, найдена ли строка "viagra"
в строках темы ваших писем.
Позволяет настроить некоторые фиктивные данныедля иллюстрации:
subjects <- c("Buy my viagra", "Buy my Sildenafil citrate",
"UK Lottery Win!!!!!")
names(subjects) <- rep("Subject", 3)
spamdata <- list(list(Header = subjects[1]), list(Header = subjects[2]),
list(Header = subjects[3]))
Далее мы создаем вектор words
для хранения результата каждой итерации цикла.Вы не хотите увеличивать words
или любой другой объект на каждой итерации - это приведет к копированию и замедлит ваш цикл.Вместо этого выделите хранилище, прежде чем начать - здесь используется длина списка, по которому мы хотим выполнить цикл:
words <- logical(length = length(spamdata))
Вы можете настроить цикл следующим образом:
## seq_along() creates a sequence of 1:length(spamdata)
for(i in seq_along(spamdata)) {
words[ i ] <- grepl("viagra", spamdata[[ i ]]$Header["Subject"])
}
Тогда мы можемпосмотрите на words
:
> words
[1] TRUE FALSE FALSE
Что соответствует тому, что мы знаем по выдуманным предметам.
Обратите внимание, как мы использовали i
в качестве заполнителя для 1
, 2
и 3
- на каждой итерации цикла i
принимает следующее значение в последовательности 1
, 2
, 3
, чтобы мы могли i) получить доступ к i
-ому компоненту spamdata
чтобы получить следующую строку темы, и ii) получить доступ к i
-ому элементу words
, чтобы сохранить результат вызова grepl()
.
Обратите внимание, что вместов неявном цикле мы могли бы также использовать функции sapply()
или lapply()
, которые создают цикл для вас, но могут потребовать немного работы для написания пользовательской функции.Вместо непосредственного использования grepl()
мы можем написать обертку:
foo <- function(x) {
grepl("viagra", x$Header["Subject"])
}
В приведенной выше функции мы используем x
вместо имени списка spamdata
, потому что когда цикл lapply()
и sapply()
в списке spamdata
отдельные компоненты (на которые ссылается spamdata[[i]]
в цикле for()
) передаются нашей функции в качестве аргумента x
, поэтому нам нужно ссылаться только на x
в вызове grepl()
.
Вот как мы могли бы использовать нашу функцию-обертку foo()
в lapply()
или sapply()
, сначала lapply()
:
> lapply(spamdata, foo)
[[1]]
[1] TRUE
[[2]]
[1] FALSE
[[3]]
[1] FALSE
sapply()
упростит возвращаемый объект, гдевозможно, следующим образом:
> sapply(spamdata, foo)
[1] TRUE FALSE FALSE
Кроме этого, они работают аналогично.
Обратите внимание, что мы можем сделать нашу функцию-обертку foo()
более полезной, позволив ей принять аргумент, определяющий спамслово, которое вы хотите найти:
foo <- function(x, string) {
grepl(string, x$Header["Subject"])
}
Мы можем передать дополнительные аргументы нашим функциям с помощью lapply()
и sapply()
, например:
> sapply(spamdata, foo, string = "viagra")
[1] TRUE FALSE FALSE
> sapply(spamdata, foo, string = "Lottery")
[1] FALSE FALSE TRUE
Что вы найдете наиболее полезным(for()
loop или lapply()
, sapply()
версии) будет зависеть от вашей фоновой программыи который вы найдете наиболее знакомым.Иногда for()
проще и проще в использовании, но, возможно, более многословно (что не всегда плохо!), Тогда как lapply()
и sapply()
довольно лаконичны и полезны, когда вам не нужно прыгать через обручисоздать работоспособную функцию-обертку.