忽略DF中的NA列(用于计算)而不删除它

时间:2012-05-31 10:20:02

标签: r

我目前有一个函数,它在我的相关矩阵中查找每个文件的最佳相关性。我正在处理list.files。这是功能:

get.max.cor <- function(station, mat){
        mat[row(mat) == col(mat)] <- -Inf        
        which( mat[station, ] == max(mat[station, ],na.rm=TRUE) )
     }

如果我有这样的相关矩阵(没有NA值):

cor1 <- read.table(text="
ST208     ST209     ST210     ST211     ST212
ST208 1.0000000 0.8646358 0.8104837 0.8899451 0.7486417
ST209 0.8646358 1.0000000 0.9335584 0.8392696 0.8676857
ST210 0.8104837 0.9335584 1.0000000 0.8304132 0.9141465
ST211 0.8899451 0.8392696 0.8304132 1.0000000 0.8064669
ST212 0.7486417 0.8676857 0.9141465 0.8064669 1.0000000
", header=TRUE)

完美无缺。如果我有一个与一些NA(但不仅仅是NA)的相关矩阵,如下所示:

cor2 <- read.table(text="
ST208     ST209     ST210     ST211     ST212
ST208 1.0000000 NA 0.9666491 0.9573701 0.9233598
ST209 NA 1.0000000 0.9744054 0.9577192 0.9346706
ST210 0.9666491 0.9744054 1.0000000 0.9460145 0.9582683
ST211 0.9573701 0.9577192 0.9460145 1.0000000 NA
ST212 0.9233598 0.9346706 0.9582683 NA 1.0000000
", header=TRUE)

由于na.rm = TRUE,它仍然有效,但是当我有一个没有数据的文件时,列中的NAs就像这样:

cor3 <- read.table(text="
ST208     ST209     ST210     ST211     ST212
ST208 1.0000000 NA 0.8104837 0.8899451 0.7486417
ST209 NA NA NA NA NA
ST210 0.8104837 NA 1.0000000 0.8304132 0.9141465
ST211 0.8899451 NA 0.8304132 1.0000000 0.8064669
ST212 0.7486417 NA 0.9141465 0.8064669 1.0000000
", header=TRUE)

它当然不起作用,因为没有非NA值,因此,该文件没有最大相关性。 这就是为什么我有这个错误:0(非na)的情况。 我试图删除NA列,但是当我在list.files上工作时,列表和矩阵中的文件数量将不同。我在网上搜索,但我只找到了一些关于删除NA列的主题。 就我而言,我想忽略这些NA列而不删除它们。

我想对R说:当你在相关矩阵中寻找每个文件的最高相关性时,如果你看到一个没有相关系数的文件(只有NAs列),不要对它做任何事情,保持这样,然后转到下一个文件(下一列或下一行)。 我还试图把其他{NA}或其他{NULL}来避免这个问题,但它仍然不起作用。

有人知道如何解决这个问题吗? 非常感谢你。

祝你好运 杰弗里


感谢您的所有答案。

我认为它现在适用于使用Joran代码的NA列。你也是真正的乔兰。我现在在下一个函数上有一个错误,它用于处理get.max.cor的输出。

    na.fill <- function(x, y){        
            i <- is.na(x[1:8700,1])
            xx <- y[1:8700,1]        
            new <- data.frame(xx=xx)
            x[1:8700,1][i] <- predict(lm(x[1:8700,1]~xx, na.action=na.exclude), new)[i]
            x        
        }

process.all <- function(df.list, mat){

        f <- function(station)
             na.fill(df.list[[ station ]], df.list[[ max.cor[station] ]])

        g <- function(station){
        x <- df.list[[station]]
        if(any(is.na(x[1:8700,1]))){
            mat[row(mat) == col(mat)] <- -Inf
            nas <- which(is.na(x[1:8700,1]))
            ord <- order(mat[station, ], decreasing = TRUE)[-c(1, ncol(mat))]
            for(y in ord){
                if(all(!is.na(df.list[[y]][1:8700,1][nas]))){
                    xx <- df.list[[y]][1:8700,1]
                    new <- data.frame(xx=xx)
                    x[1:8700,1][nas] <- predict(lm(x[1:8700,1]~xx, na.action=na.exclude), new)[nas]
                    break
                }
            }
        }
        x
    }             

        n <- length(df.list)
        nms <- names(df.list)
        max.cor <- sapply(seq.int(n), get.max.cor, corhiver2008capt1)
        df.list <- lapply(seq.int(n), f)
        df.list <- lapply(seq.int(n), g)
        names(df.list) <- nms
        df.list
    }

    refill <- process.all(lst, corhiver2008capt1)
    refill <- as.data.frame(refill)
    capt1_hiver <- refill[1:8700,]

此功能用于根据最佳关联文件填充我的文件(我之前选择它)。 我的错误是:

Error in model.frame.default(formula = x[1:8700, 1] ~ xx, na.action = na.exclude,  : 
  invalid type (NULL) for variable 'xx'

这可能是由于我的相关矩阵的“空列”。 xx文件中没有数据(没有相关的文件)。 如何在不修改数据维度的情况下继续计算并忽略(或不执行任何操作)NULL文件(保留NA文件)?目前,只有当我选择带有数据的文件(而不仅仅是NA)时,它才有效。

2 个答案:

答案 0 :(得分:3)

所以我不完全确定你在这里使用你的示例代码得到了什么,但是我们走了。

当我在所有缺失值的cor3行上运行你的函数时,我得到了这个:

> get.max.cor("ST209",cor3)
[1] 2

这既不是错误也不是警告,但它可能不是你想要的。你写的函数用-Inf替换对角元素,因为每个工作站可能与自身完全相关,你不希望它是最大的。

这意味着下一行不会在 NA值的行上运行;那里有一个-Inf。因此,na.rm = TRUE会抛出除-Inf之外的所有值,因为这就是剩下的所有内容,它是最大值。

显然,这不是你想要的。但是你还没有真正指定如何使用这个函数来遍历行,所以我不得不推测。如果修改函数以检查最大值是否有限:

get.max.cor <- function(station, mat){
     mat[row(mat) == col(mat)] <- -Inf
     m <- max(mat[station, ],na.rm=TRUE)
     if (is.finite(m)) {return(which( mat[station, ] == m ))}
     else {return(NA)}
}

当该行为NA个值时,您可以返回NA。但是你可能还需要使用你用来处理NA输出的任何代码来处理get.max.cor(由于你没有提供它,我无法帮助你)

答案 1 :(得分:0)

正如达纳斯所说,你得到了你想要的东西。但是,这是实现测试的一种方法,如果它证明是有用的。

if ( sum(!is.na(cor3[j,])) == 0 ) #all values in j-th row are NA {
   output(j)= NULL
}