R编程 - 带数据帧的pmax

时间:2017-11-26 05:34:19

标签: r

我试图在我的程序中使用pmax函数。我有一个数字数据框,我试图将它与一个数字进行比较。输出有NA。

我发现数据帧不适用于pmax,因此我将数据帧更改为矩阵。它奏效了。我很好奇为什么数据帧返回NA。这与回收有关吗?

代码: -

mat <- matrix(runif(500), nrow = 20, ncol = 5)
df <- as.data.frame(mat)


pmax(mat, .5) # No NA's

pmax(df, .5) # Many NA's

1 个答案:

答案 0 :(得分:3)

这是第二个参数上的值复制没有完全回收的问题之一,即它取决于列数。这可能是原因

rep(0.5, ncol(df))[df < 0.5]
#[1] 0.5 0.5  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
#[41]  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA

请注意,对于前两个值,正确地更改0.5,因为对于那些元素df < 0.5,逻辑矩阵为TRUE,而不是这种情况,因为0.5仅根据列数进行复制。 / p>

假设我们查看pmax

mmm[change] <- each[change]

有问题。我们可以print输出&#39;每个&#39;来检查输出。并且每次[改变]。如果我们修改函数以包含print语句

pmax2 <- function (..., na.rm = FALSE) 
{
    elts <- list(...)
    if (length(elts) == 0L) 
        stop("no arguments")
    if (all(vapply(elts, function(x) is.atomic(x) && !is.object(x), 
        NA))) {
        mmm <- .Internal(pmax(na.rm, ...))
        mostattributes(mmm) <- attributes(elts[[1L]])
    }
    else {
        mmm <- elts[[1L]]
        has.na <- FALSE
        as <- methods::as
        asL <- function(x) if (isS4(x)) 
            as(x, "logical")
        else x
        for (each in elts[-1L]) {
            l1 <- length(each)
            l2 <- length(mmm)
            if (l2 && (l2 < l1 || !l1)) {
                if (l1%%l2) 
                  warning("an argument will be fractionally recycled")
                mmm <- rep(mmm, length.out = l1)
            }
            else if (l1 && (l1 < l2 || !l2)) {
                if (l2%%l1) 
                  warning("an argument will be fractionally recycled")
                each <- rep(each, length.out = l2)
            }
            na.m <- is.na(mmm)
            na.e <- is.na(each)
            if (has.na || (has.na <- any(na.m) || any(na.e))) {
                if (any(na.m <- asL(na.m))) 
                  mmm[na.m] <- each[na.m]
                if (any(na.e <- asL(na.e))) 
                  each[na.e] <- mmm[na.e]
            }
            nS4 <- !isS4(mmm)
            if (isS4(change <- mmm < each) && (nS4 || !isS4(each))) 
                change <- as(change, "logical")
            change <- change & !is.na(change)
            print(change)
            mmm[change] <- each[change]
            print(each)
            print(each[change])
            if (has.na && !na.rm) 
                mmm[na.m | na.e] <- NA
            if (nS4) 
                mostattributes(mmm) <- attributes(elts[[1L]])
        }
    }
    mmm
}

现在,我们根据{d}&#39;

上的print检查pmax2输出
invisible(pmax2(df, 0.5))
#       V1    V2    V3    V4    V5
# [1,]  TRUE  TRUE  TRUE  TRUE FALSE
# [2,]  TRUE FALSE  TRUE  TRUE  TRUE
# [3,] FALSE FALSE  TRUE  TRUE FALSE
# [4,] FALSE  TRUE  TRUE  TRUE  TRUE
# [5,] FALSE  TRUE  TRUE FALSE  TRUE
# [6,] FALSE FALSE  TRUE  TRUE  TRUE
# [7,]  TRUE  TRUE  TRUE FALSE  TRUE
# [8,] FALSE FALSE  TRUE FALSE FALSE
# [9,] FALSE FALSE  TRUE FALSE  TRUE
#[10,]  TRUE  TRUE  TRUE  TRUE FALSE
#[11,] FALSE  TRUE  TRUE  TRUE  TRUE
#[12,]  TRUE  TRUE FALSE  TRUE FALSE
#[13,] FALSE  TRUE  TRUE  TRUE FALSE
#[14,] FALSE  TRUE FALSE FALSE  TRUE
#[15,]  TRUE FALSE FALSE FALSE  TRUE
#[16,] FALSE  TRUE FALSE  TRUE FALSE
#[17,]  TRUE FALSE  TRUE FALSE FALSE
#[18,]  TRUE FALSE  TRUE FALSE  TRUE
#[19,] FALSE FALSE  TRUE  TRUE  TRUE
#[20,]  TRUE FALSE  TRUE FALSE  TRUE
#[1] 0.5 0.5 0.5 0.5 0.5
# [1] 0.5 0.5  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
#[41]  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA

请注意,这与前面提到的rep完全相同。

但是,在matrix上,由于if/else语句

,因此未执行此操作
invisible(pmax2(mat, 0.5))

什么都没有打印

与单个元素比pmax和该元素相比,最好在matrix上应用data.frame。否则,我们可以unlist data.frame或将其转换为matrix

all.equal(c(pmax(mat, .5)), pmax(unlist(df), .5), check.attributes = FALSE)
#[1] TRUE

数据

set.seed(24)
mat <- matrix(runif(500), nrow = 20, ncol = 5)
df <- as.data.frame(mat)