8

我想使用 R 将具有非唯一行名的表中的数值数据汇总到具有唯一行名的结果表中,其中的值使用自定义函数进行汇总。总结逻辑是:如果最大值与最小值之比 < 1.5,则使用值的平均值,否则使用中值。因为表很大,所以我尝试使用reshape2包中的 melt() 和 cast() 函数。

# 具有非唯一行名的示例表
tab <- data.frame(gene=rep(letters[1:3], each=3), s1=runif(9), s2=runif(9))
# 融化
tab.melt <- 融化(标签,id=1)
# 用逻辑总结的函数:如果 max/min < 1.5 则表示平均值,否则为中位数
总结 <- 函数(x){ifelse(max(x)/min(x)<1.5, mean(x), median(x))}
# 使用汇总值强制转换
dcast(tab.melt,基因~变量,总结)

上面的最后一行代码会导致错误通知。

vapply 中的错误(索引,乐趣,.default):
  值必须是“逻辑”类型,
 但 FUN(X[[1]]) 结果是类型“双”
另外:警告信息:
1:在 max(x) 中:max 没有非缺失参数;返回-Inf
2:在 min(x) 中:min 没有非缺失参数;返回 Inf

我究竟做错了什么?请注意,如果 summarise 函数只返回 min() 或 max(),则不会出现错误,但会出现有关“没有非缺失参数”的警告消息。谢谢你的任何建议。

(我要使用的实际表是 200x10000 的表。)

4

2 回答 2

9

简短回答:为填充提供一个值,如下所示 acast(tab.melt,gene~variable,summary,fill=0)

长答案:看起来你的函数在被传递给 vapply 函数之前被如下包装(dcast 调用 cast 调用 vaggregate 调用 vapply):

fun <- function(i) {
    if (length(i) == 0) 
        return(.default)
    .fun(.value[i], ...)
}

要找出 .default 应该是什么,执行此代码

if (is.null(.default)) {
    .default <- .fun(.value[0])
}

即 .value[0] 被传递给函数。当 x 为 numeric(0) 时,min(x) 或 max(x) 返回 Inf 或 -Inf。但是,max(x)/min(x) 返回具有逻辑类的 NaN。所以当执行 vapply 时

vapply(indices, fun, .default)

默认值为逻辑类(由 vapply 用作模板),该函数在开始返回双精度时失败。

于 2011-01-29T08:02:04.183 回答
2

dcast() 尝试将缺失组合的值设置为默认值。

您可以通过 fill 参数指定此值,但如果 fill=NULL,则使用 fun(0-lenght vector) 返回的值(即这里的 summarise(numeric(0)))作为默认值。

请看 ?dcast

那么,这里有一个解决方法:

 dcast(tab.melt, gene~variable, summarize, fill=NaN)
于 2011-01-29T08:00:57.973 回答