我试图在我的程序中使用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
答案 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)