【问题标题】:ignore NA column in a DF (for calculation) without removing it忽略 DF 中的 NA 列(用于计算)而不删除它
【发布时间】:2012-06-01 22:22:40
【问题描述】:

目前我有一个函数,它为我的相关矩阵中的每个文件寻找最佳相关性。我正在处理 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,它仍然有效,但是当我有一个没有数据的文件时,因此列中只有 NA,如下所示:

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 (non-na) 案例。 我试图删除 NA 列,但是当我处理 list.files 时,列表和矩阵中的文件数将不一样。我在网上搜索,但只找到了一些关于删除 NA 列的主题。 就我而言,我想忽略这些 NA 列而不删除它们。

我想对 R 说:当你在相关矩阵中寻找每个文件的最高相关性时,如果你看到一个没有相关系数的文件(只有 NAs 列),不要对它做任何事情,保持这样并转到下一个文件(下一列或下一行)。 我也尝试使用 else {NA} 或 else {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'

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

【问题讨论】:

  • 实际上你会收到警告但不是错误x&lt;-c(NA,NA); which(x==max(x,na.rm=TRUE))。无论如何,当您拥有所有 NA 时,您的函数会返回 integer(0) 这没什么(如您所愿)。
  • 不要用回复或附加问题编辑您的问题。如果您还有其他问题,您应该提出一个新问题。

标签: r


【解决方案1】:

所以我不完全确定你的示例代码在这里得到了什么,但我们开始吧。

当我在 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。但是,您可能还需要使用您用来处理get.max.cor 输出的任何代码来处理NA(我无法真正提供帮助,因为您没有提供它)。

【讨论】:

    【解决方案2】:

    正如 danas 所说,你得到了你可能想要的东西。但是,如果它证明有帮助,这是实现测试的一种方法。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-30
      • 1970-01-01
      • 2013-03-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多