带错误处理的ddply cor.test

时间:2014-04-18 15:06:54

标签: r

我在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()的包装器,但似乎无法将该变量传递到我的结果数据框中。

如何解决这个问题的任何帮助都将非常感激。

1 个答案:

答案 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.testmerge执行哪些列来唯一地命名列。{{1}并没有用后缀命名它们。可能有更好的方法,可能使用mergesuffixes参数。

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
    }
}