R语言sink、capture.output函数使用问题:循环输出为空/动态生成文件名
R分析结果导出txt问题解决方案
问题1:repeat循环中sink导出文件内容为空
原因
R交互式环境下单独执行代码时,summary()返回的结果会被自动打印到控制台,因此sink()可以捕获到内容;但在循环内部,函数返回值不会自动打印,没有输出流被sink()捕获,最终生成的文件就为空。
另外注意你手动逐行编写的代码中增加了BvA == "Before"的过滤条件,模型公式也换成了Location*Season,如果循环代码需要和手动执行逻辑一致,要同步修改对应部分。
修正代码
i = 1 repeat{ # 如需匹配手动代码逻辑,可在此处添加BvA过滤条件 tableA<-subset(coral, Location=="D7") tableB<-subset(coral, Location==unique(coral$Location)[i]) tab<-rbind(tableA,tableB) # 如需匹配手动代码逻辑,可在此处修改模型公式为Location*Season aov.res<-aov(cbind(AJ,A,DG,SG,EA)~Location*BvA,data = tab) sink(paste("BA X CI", i,".txt")) # 显式打印summary结果,让sink可以捕获输出 print(summary(aov.res)) sink() if(i >= 6) break i = i+1 }
问题2:capture.output无法拼接变量生成文件名
原因
你在capture.output的file参数位置传入了多个零散的字符串,R只会将第一个字符串识别为文件名,后续的i和.txt被判定为无效参数,因此只会生成名为BA X CI的文件。
修正代码
和sink的用法一致,用paste()函数拼接文件名的各个部分,作为file参数的完整值即可:
i = 1 repeat{ tableA<-subset(coral, Location=="D7") tableB<-subset(coral, Location==unique(coral$Location)[i]) tab<-rbind(tableA,tableB) aov.res<-aov(cbind(AJ,A,DG,SG,EA)~Location*BvA,data = tab) # 用paste拼接完整文件名 capture.output(summary(aov.res), file = paste("BA X CI", i, ".txt")) if(i >= 6) break i = i+1 }
额外优化建议
你可以用for循环代替repeat循环,代码更简洁,也不容易出现计数错误:
for (i in 1:6) { tableA<-subset(coral, Location=="D7") tableB<-subset(coral, Location==unique(coral$Location)[i]) tab<-rbind(tableA,tableB) aov.res<-aov(cbind(AJ,A,DG,SG,EA)~Location*BvA,data = tab) capture.output(print(summary(aov.res)), file = paste("BA X CI", i, ".txt")) }
内容的提问来源于stack exchange,提问作者KELPman
相关产品推荐
相关产品推荐

