如何在R编程中启动for循环

use*_*428 4 r

我是编程的新手,我编写了一个代码,可以找到第一封电子邮件的垃圾邮件,但我想编写一个for循环来为所有电子邮件执行此操作.任何帮助,将不胜感激.谢谢.

words = grepl("viagra", spamdata[[ 1 ]]$header[ "Subject"])
Run Code Online (Sandbox Code Playgroud)

Rei*_*son 15

我假设您想循环遍历元素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]))
Run Code Online (Sandbox Code Playgroud)

接下来,我们创建一个向量words来保存循环的每次迭代的结果.您不希望words在每次迭代中增长或任何其他对象 - 这将强制复制并将减慢您的循环.而是在开始之前分配存储 - 这里使用我们想要循环的列表的长度:

words <- logical(length = length(spamdata))
Run Code Online (Sandbox Code Playgroud)

你可以设置一个循环

## seq_along() creates a sequence of 1:length(spamdata) 
for(i in seq_along(spamdata)) {
    words[ i ] <- grepl("viagra", spamdata[[ i ]]$Header["Subject"])
}
Run Code Online (Sandbox Code Playgroud)

然后我们可以看看words:

> words
[1]  TRUE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)

这与我们从制作科目中所知道的相符.

注意我们是如何使用i作为占位符为1,2,和3-在循环的每次迭代中,i将在下次的值序列中1,2,3所以我们可以ⅰ)访问i的个分量spamdata,以获得下一个主题行, ⅱ)访问存储调用结果的ith元素.wordsgrepl()

请注意,我们也可以使用sapply()lapply()函数来代替隐式循环,这些函数为您创建循环,但可能需要一些工作来编写自定义函数.grepl()我们可以编写一个包装器而不是直接使用:

foo <- function(x) {
    grepl("viagra", x$Header["Subject"])
}
Run Code Online (Sandbox Code Playgroud)

在上面的函数中,我们使用x了列表名称,而不是spamdata因为当lapply()sapply() 循环在spamdata列表中,各个组件(通过引用spamdata[[i]]for()循环中)获得通过我们作为参数的功能x,所以我们只需要参考xgrepl()呼叫.

这就是我们如何foo()lapply()or中使用我们的包装函数sapply(),首先lapply():

> lapply(spamdata, foo)
[[1]]
[1] TRUE

[[2]]
[1] FALSE

[[3]]
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

sapply() 将尽可能简化返回的对象,如下所示:

> sapply(spamdata, foo)
[1]  TRUE FALSE FALSE
Run Code Online (Sandbox Code Playgroud)

除此之外,他们的工作方式相似.

注意我们可以foo()通过允许它定义您要搜索的垃圾邮件单词的参数来使我们的包装函数更有用:

foo <- function(x, string) {
    grepl(string, x$Header["Subject"])
}
Run Code Online (Sandbox Code Playgroud)

我们可以通过额外的参数给我们的功能lapply()sapply()这样的:

> sapply(spamdata, foo, string = "viagra")
[1]  TRUE FALSE FALSE
> sapply(spamdata, foo, string = "Lottery")
[1] FALSE FALSE  TRUE
Run Code Online (Sandbox Code Playgroud)

您将找到最有用的(for()循环或lapply(),sapply()版本)将取决于你的编程背景,哪些是你觉得最熟悉的.有时for()是更方便,更易于使用,但也许更详细的(这并不总是一件坏事!),而lapply()sapply()相当简洁,在这里你不需要赴汤蹈火创建一个可行的包装函数是有用的.