146-在不断地报错和试错过程中提升自己-R发邮件

刘小泽写于19.11.9 记得之前Jimmy说过,他给别人发邮件经常使用R包,这一点就很新鲜,并且大大方便了批量发送。我感觉很好奇,就想尝试一下,看看能不能成功

首先搜索使用了什么R包

只需要把自己的需求简单描述,浏览器都能给我们答案,例如:

image-20191109110555731

发现搜到的大多指向了mailR这个包

明确了方向,开始前进

以下操作基于Mac Mojave的Rstudio,R版本3.6.1

如果想操作,一定要先看完,中间有些坑就可以帮你避免

貌似这个包运行很简单,安装包完事一句send.mail(...)函数就搞定啦!

其实不然,首先会遇到的坑就是解决它的依赖

这个包依赖于java

其实碰到java就有点头疼了,我对java的初始看法是:它的版本复杂,而且用不对就运行不成功,报错也稀奇古怪。这一切的认知都”归功“于IGV,它也是个难缠的家伙,记得当时安装软件还花费了一些功夫: 必备可视化Integrative Genomic Viewer(IGV)

不过没关系,先探索一下。直接install.packages('mailR',dependencies = T)安装肯定不行,因为它事先需要安装一个rJava的依赖包。

rJava的安装踩坑

运行这句命令install.packages('rJava',dependencies = T)

如果不出现报错,那么恭喜你,说明你的电脑中java版本是正确的。

不过大多数情况没有这么巧,很有可能出现以下报错:

报错信息很长,但不要害怕!我们要相信写R包的作者都有一颗善心,它们一定会把解决方案或者线索写在报错信息中。能不能成功和作者”呼应“上,就看自己了

# 出现报错(我们只看有用的信息)
# Unable to find any JVMs matching version "(null)".
# No Java runtime present, try --request to install.
# Library not loaded: /Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/lib/server/libjvm.dylib

可见它在说,我的电脑目前mac上只有JDK 13,估计是版本太高。看一眼报错,这不是让我们去用jdk-11.0.1.jdk这个版本吗?

tip:JDK的版本命名是这样的:jdk-interim.update.patch.jdk

那么就要去找对应的历史版本:https://jdk.java.net/archive/,找到11.0.1版本后下载,结果会是一个tar.gz文件,将其解压后放在/Library/Java/JavaVirtualMachines目录

最后使用java --version查看版本

喜旧厌新

有了旧版本,就要删掉新版本,在terminal或者iterms中输入:

cd /Library/Java/JavaVirtualMachines
sudo rm -rf jdk-13.0.1.jdk

然后再进行旧版本的配置

sudo R CMD javareconf

结果就能看到版本变化了:Java version: 11.0.1

image-20191109112316842

以上内容参考了:https://blog.csdn.net/weixin_38986122/article/details/80931223 中的”在R中安装rJava及建立连接“部分

版本正确了,再次迈出一小步
install.packages('rJava',dependencies = T)
library(rJava)
install.packages('mailR',dependencies = T)
library(mailR)

没有出现报错,可见只要按照报错的要求操作,缺啥补啥,就没问题

走到这里,其实只成功了三分之一

配置邮箱

发邮件不是这么随便的,毕竟我们登陆邮箱还要密码呢,程序不会这么智能地跳过输入密码这一步。但又为了方便快捷,省事省力地去批量发送,而且要强调保密性(总不能把自己的真实邮箱密码在代码中展示吧)。于是代码中添加了一个参数passwd

不过不要误解,这个参数不是要让你输入邮箱的密码,而是一个授权码

那么怎么获取这个授权码呢?

以163旗下的yeah.cn邮箱为例,我们登录上以后,会在设置中找到POP3/SMTP/IMAP选项,相信很多人都没有用过这个功能,我也是第一次,这个没关系,以后你就能教别人使用了:

image-20191109113137592

这两项都需要用手机发一个短信,这个设置一步步操作就好,该打开的服务打开就行。授权码设置一个不同于密码的熟记的就好

有了这个授权码,可以看看代码怎么写了

代码很简单,一共就需要提供自己的邮箱、授权码、别人的邮箱

如果只是针对一个收件人的话:

sender <- "自己的邮箱~我的是bioinfoplanet520@yeah.net"
recipients <- c("你的收件人")
send.mail(from = sender,
          to = recipients,
          subject = "Program Done.",
          body = "My program is finished.",
          smtp = list(host.name = "smtp.yeah.net", port = 465,
                      user.name = "自己的邮箱~我的是bioinfoplanet520@yeah.net",
                      passwd = "刚才设置的授权码", ssl = TRUE),
          authenticate = TRUE,
          send = TRUE)

下一个坑来啦

如果这时直接运行代码,很有可能会报错,而且看上去报错信息很难懂(这也正是讨厌java报错的原因):

image-20191109113702111

但没关系,我们有搜索引擎,把报错搜一下:

第一次搜索得到:https://github.com/rpremraj/mailR/issues/77

其中wush978这个用户说让把两个.jar文件放到下面👇的m目录

# 在R中输入这个命令,就会出来这个包所在的位置
system.file("java", package = "mailR")

但根据他提供的信息,下载两个文件,还是报错。

于是先检查下载的文件,结果发现下载的两个命名有问题,都是1.2.0这样的名称,而不是.jar后缀

image-20191109113948842

搜索第二次:这次搜索这两个文件

在https://stackoverflow.com/questions/20020270/java-lang-noclassdeffounderror-javax-activation-datahandler中Bill Shannon用户提供了信息:

这两个文件的另外的下载地址是:

https://code.google.com/archive/p/javamail-android/downloads

下载发现,这次的下载命名是对的,下载的路径也是对的

image-20191109114136775

记得重启Rstudio

解决了之前的加载包和运行代码的两个错误以后,进行重启。重启之后,再次尝试运行代码

这一次,惊喜出现了,等待几秒后,返回了正常的结果

image-20191109114328201

然后我就在我的收件箱找到了:image-20191109114423048

image-20191109114551144

总结

好,既然发一封没有问题,那么用R语言,处理批量发送邮件,也不是一件难事了

发现自己越来越不害怕、不反感报错了。而是能冷静下来,仔细思考为什么会有这种报错。相信问题是一定能够解决的,报错只会更加方便地去寻找解决方案而已

Yunze Liu
Yunze Liu
Bioinformatics Sharer

Co-founder of Bioinfoplanet(生信星球)

Next
Previous

Related