我在R中遇到问题,我在数据框上运行cor.test,其中有多个组。
我试图获得一个因变量和数据帧中包含的多个独立变量的相关系数。数据框有2个分组列,用于对数据进行子集化。这是一个例子:
DF <- data.frame(group1=rep(1:4,3),group2=rep(1:2,6),x=rnorm(12),v1=rnorm(12),v2=rnorm(12),v3=rnorm(12))
我创建了以下脚本,使用plyr计算每个组的相关系数,然后遍历每个变量。
library(plyr)
group_cor <- function(DF,x,y)
{
return(data.frame(cor = cor.test(DF[,x], DF[,y])$estimate))
}
resultDF <- ddply(DF, .(group1,group2), group_cor,3,4)
for(i in 5:6){
resultDF2 <- ddply(DF, .(group1,group2), group_cor,3,i)
resultDF <- merge(resultDF,resultDF2,by=c("group1","group2"))
rm(resultDF2)
}
这很好用。我遇到的问题是当组中没有足够的值来计算相关系数时。例如:当我更改上面创建的数据框时,现在包含一些关键NA值,然后尝试运行相同的循环:
DF[c(2,6,10),5]=NA
for(i in 5:6){
resultDF2 <- ddply(DF, .(group1,group2), group_cor,3,i)
resultDF <- merge(resultDF,resultDF2,by=c("group1","group2"))
rm(resultDF2)
}
我收到以下错误&#34;错误:没有足够的有限观察&#34;
我理解为什么会出现这个错误,并且我不希望得到这些情况的相关系数。但我想要做的是传递一个空值并继续下一组,而不是在错误时停止我的代码。
我尝试过使用带有try()的包装器,但似乎无法将该变量传递到我的结果数据框中。
如何解决这个问题的任何帮助都将非常感激。
答案 0 :(得分:1)
我总是忘记使用try
如果我没有使用它,哦,一天或某事。 This link让我记住了基础知识。
对于您的功能,您可以像这样添加它:
group_cor = function(DF,x,y) {
check = try(cor.test(DF[,x], DF[,y])$estimate, silent = TRUE)
if(class(check) != "try-error")
return(data.frame(cor = cor.test(DF[,x], DF[,y])$estimate))
}
但是,对于有错误的组,不会返回任何内容。如果在合并时使用all
参数,那实际上没问题。这是另一种合并方式,将所有内容保存到包含lapply
的列表中,然后与Reduce
合并。
allcor = lapply(4:6, function(i) ddply(DF, .(group1,group2), group_cor, 3, i))
Reduce(function(...) merge(..., by = c("group1", "group2"), all = TRUE), allcor)
如果您想在功能中填写NA而不是等待使用merge
填写,您可以将功能更改为:
group_cor2 = function(DF,x,y) {
check = try(cor.test(DF[,x], DF[,y])$estimate, silent = TRUE)
if(class(check) == "try-error")
return(data.frame(cor = NA))
return(data.frame(cor = cor.test(DF[,x], DF[,y])$estimate))
}
最后(在问题范围之外),根据您对输出的处理方式,您可以考虑根据cor.test
为merge
执行哪些列来唯一地命名列。{{1}并没有用后缀命名它们。可能有更好的方法,可能使用merge
和suffixes
参数。
group_cor3 = function(DF,x,y) {
check = try(cor.test(DF[,x], DF[,y])$estimate, silent = TRUE)
if(class(check) != "try-error") {
dat = data.frame(cor = cor.test(DF[,x], DF[,y])$estimate)
names(dat) = paste("cor", x, "vs", y, sep = ".")
dat
}
}