R中xtabs和aggregate之间的na.action不一致

2024-03-25

我有以下数据框:

x <- data.frame(A = c("Y", "Y", "Z", NA),
                B = c(NA, TRUE, FALSE, TRUE),
                C = c(TRUE, TRUE, NA, FALSE))

我需要计算下表xtabs:

A      B C
  Y    1 2
  Z    0 0
  <NA> 1 0

我被告知要使用na.action = NULL https://stackoverflow.com/questions/56237951/xtabs-counts-with-na-and-na-action-na-pass-in-r,它确实返回我需要的表:

xtabs(formula = cbind(B, C) ~ A,
      data = x,
      addNA = TRUE,
      na.action = NULL)

A      B C
  Y    1 2
  Z    0 0
  <NA> 1 0

然而,na.action = na.pass返回不同的表:

xtabs(formula = cbind(B, C) ~ A,
      data = x,
      addNA = TRUE,
      na.action = na.pass)

A       B  C
  Y        2
  Z     0   
  <NA>  1  0

但文档xtabs says:

NA动作
当它是 na.pass 并且公式有左侧(带有计数)时, 使用 sum(*, na.rm = TRUE) 代替 sum(*) 进行计数。

With aggregate, na.action = na.pass返回预期结果(并且还na.action = NULL):

aggregate(formula = cbind(B, C) ~ addNA(A),
          data = x,
          FUN = sum,
          na.rm = TRUE,
          na.action = na.pass) # same result with na.action = NULL

  addNA(A) B C
1            Y 1 2
2            Z 0 0
3         <NA> 1 0

虽然我得到了我需要的桌子xtabs,我不明白的行为na.action in xtabs从文档中。所以我的问题是:

  • 的行为是na.action in xtabs与文档一致吗?除非我错过了什么,na.action = na.pass不会导致sum(*, na.rm = TRUE).
  • Is na.action = NULL记录在某处?
  • In xtabs源代码有na.rm <- identical(naAct, quote(na.omit)) || identical(naAct, na.omit) || identical(naAct, "na.omit")。但我什么也没看到na.action = na.pass and na.action = NULL。怎么办na.action = na.pass and na.action = NULL work?

如果不描述如何进行,很难给出规范的答案xtabs作品。如果我们逐步查看其源代码的要点,我们就会清楚地看到发生了什么。

经过一些基本的类型检查后,调用xtabs在内部工作,首先使用以下命令创建公式中包含的所有变量的数据框stats::model.frame,正是针对这一点,na.action参数已传递。

它这样做的方式非常聪明。xtabs首先复制您通过以下方式拨打的电话match.call, 像这样:

m <- match.call(expand.dots = FALSE)

然后它去掉不需要传递给的参数stats::model.frame像这样:

m$... <- m$exclude <- m$drop.unused.levels <- m$sparse <- m$addNA <- NULL

正如帮助文件中所承诺的,如果addNA is TRUE and na.action缺失,现在默认为na.pass:

    if (addNA && missing(na.action)) 
        m$na.action <- quote(na.pass)

然后它更改要调用的函数xtabs to stats::model.frame像这样:

m[[1L]] <- quote(stats::model.frame)

所以对象m是一个调用(也是一个独立的代表),在您的情况下看起来像这样:

stats::model.frame(formula = cbind(B, C) ~ A, data = list(A = structure(c(1L, 
1L, 2L, NA), .Label = c("Y", "Z"), class = "factor"), B = c(NA, TRUE, FALSE, TRUE), 
C = c(TRUE, TRUE, NA, FALSE)), na.action = NULL)

请注意,您的na.action = NULL已传递给此调用。这具有保留所有NA框架中的值。当评估上述调用时,它会给出以下数据框:

eval(m)
#>   cbind(B, C).B cbind(B, C).C    A
#> 1            NA          TRUE    Y
#> 2          TRUE          TRUE    Y
#> 3         FALSE            NA    Z
#> 4          TRUE         FALSE <NA>

请注意,如果您通过了,这与您得到的结果相同na.action = na.pass:

stats::model.frame(formula = cbind(B, C) ~ A, data = list(A = structure(c(1L, 
1L, 2L, NA), .Label = c("Y", "Z"), class = "factor"), B = c(NA, TRUE, FALSE, TRUE), 
C = c(TRUE, TRUE, NA, FALSE)), na.action = na.pass)
#>   cbind(B, C).B cbind(B, C).C    A
#> 1            NA          TRUE    Y
#> 2          TRUE          TRUE    Y
#> 3         FALSE            NA    Z
#> 4          TRUE         FALSE <NA>

然而,如果你通过了na.action = na.omit,您将只留下一行,因为只有第 2 行没有NA values.

无论如何,“模型框架”结果存储在变量中mf。然后将其分为自变量(在您的情况下为 A 列)和响应变量(在您的情况下)cbind(B, C).

响应存储在y和变量by:

        i <- attr(attr(mf, "terms"), "response")
        by <- mf[-i]
        y <- mf[[i]]

Now, by进行处理以确保每个自变量都是一个因素,并且任何NA如果您已指定,值将转换为因子水平addNA = TRUE:

    by <- lapply(by, function(u) {
        if (!is.factor(u)) 
            u <- factor(u, exclude = exclude)
        else if (has.exclude) 
            u <- factor(as.character(u), levels = setdiff(levels(u), 
                exclude), exclude = NULL)
        if (addNA) 
            u <- addNA(u, ifany = TRUE)
        u[, drop = drop.unused.levels]
    })

现在我们来到了症结所在。这na.action再次用于确定如何NA响应变量中的值将被计算在内。就你而言,自从你通过了na.action = NULL,你会看到naAct将得到存储在的值getOption("na.action"),如果您从未更改过它,则应设置为na.omit。这反过来会导致变量的值na.rm, to be TRUE:

    naAct <- if (!is.null(m$na.action)) {
        m$na.action
    }else {getOption("na.action", default = quote(na.omit))}
    na.rm <- identical(naAct, quote(na.omit)) || identical(naAct, 
        na.omit) || identical(naAct, "na.omit")

请注意,如果您已经通过na.action = na.pass, then na.rm将会FALSE如果你跟踪这段代码。

最后,我们来到了您的部分xtabs表是使用构建的sum里面一个tapply,它本身就在一个lapply.

lapply(as.data.frame(y), tapply, by, sum, na.rm = na.rm, default = 0L)

您可以看到na.rm变量用于判断是否删除NA在尝试对列求和之前先从列中取出 s。这样的结果lapply然后强制进入最终的交叉表。


那么这如何回答你的问题呢?

当文档说如果你没有通过na.action,它将默认为na.pass。但是,那na.action用于两个地方:一次在调用中model.frame并一次确定值na.rm。从源码中可以很清楚的看出,如果na.action is na.pass, then na.rmFALSE,因此您将错过包含以下内容的任何响应组的计数NA价值观。这与帮助文件中的内容相反。

解决这个问题的唯一方法就是通过na.action = NULL,因为这将允许model.frame保留NA值,但也会导致sum函数默认为na.rm.


TL;DR的文档xtabs在这一点上是错误的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

R中xtabs和aggregate之间的na.action不一致 的相关文章

  • 为什么 rbind 会抛出警告

    这与是否有更优雅的方法将不规则的数据转换为整洁的数据框 https stackoverflow com questions 25102617 are there more elegant ways to transform ragged d
  • R:邻接表到邻接矩阵

    Bonjour 我想将邻接列表 3 列 转换为邻接矩阵 在这个论坛中 我找到了多个有关如何将边列表转换为邻接矩阵的示例 我成功地为两列列表做到了这一点 我已经尝试了在网上可以找到的所有解决方案 但似乎我错过了一小步 我尝试过的 我的变量是用
  • R Shiny - 修复了 Shiny 仪表板中的侧边栏和主标题

    我有一个简化的闪亮仪表板 请参阅下面的代码 我想修复侧边栏和主标题 因此 在其他帖子的帮助下 我编写了一个 CSS 文件来解决该问题 sidebar color FFF position fixed width 220px white sp
  • 用闪亮的 R 设计 DT 中的展开行按钮

    我正在尝试设计 DT 中可用的展开行按钮的样式 样式可用here https datatables net examples api row details html 我用于创建数据表的代码是 library DT datatable cb
  • 如何使用 tidyr 将向量中字符串中的每个字符分隔到一列中

    我想将向量中的每个字符串分成列 但我做不到 library tidyr library dplyr df lt data frame x c abe bas dds eer df gt separate x c A B C sep 1 我想
  • 如何将环境变量传递给shinyapps

    我想将安全参数传递给shinyapps io部署 以便我的应用程序可以通过以下方式获取它们 Sys getenv PASSWORD X 我找不到任何相关内容deployApp函数在rsconnect包裹 您可以使用Renviron网站 or
  • 粘贴两个 data.table 列

    dt lt data table L 1 5 A letters 7 11 B letters 12 16 L A B 1 1 g l 2 2 h m 3 3 i n 4 4 j o 5 5 k p 现在我想粘贴列 A 和 B 以获得一个新
  • 如何在knitr中安装软件包?

    到目前为止 我一直在使用这段代码来加载 R 包并编写 R 文件 但我正在尝试使用knitr rm list ls all TRUE kpacks lt c ggplot2 install github devtools mapdata ne
  • 如何使用 grid.arrange 移动图例位置

    我试图在一页中排列 4 个图 将图例放在底部中心 我用它来获取其中一个图的图例 因为它们对于四个图来说是相同的 get legend lt function myggplot tmp lt ggplot gtable ggplot buil
  • 当我用一个观察值运行回归时,为什么“fastLm()”会返回结果?

    为什么fastLm 当我用一项观察进行回归时返回结果吗 下面为什么不lm and fastLm 结果相等吗 library Rcpp library RcppArmadillo library data table set seed 1 D
  • 如何在折线图中显示 Sep-12 格式的数据并抑制网格线和灰色背景?

    我正在努力使日期格式正确 数据已经是melt 格式 数据中有四个变量碰巧共享相同的数据 我只是想绘制一个简单的四线折线图 每个变量作为一条单独的线 并将 Sep 12 显示为最新数据点 我正在使用旧的 ggplot 请随意 我有两个问题 第
  • 如何在r中进行左连接[重复]

    这个问题在这里已经有答案了 我有两个数据集一和二 数据集一 a b c 111 a 1 112 b 2 113 c 3 114 d 4 115 e 5 数据集二 e d g 222 ss 11 111 ff 22 113 ww 33 114
  • 使用 SP 包中的 SpatialPoints() 转换坐标参考系 (CRS) 以创建空间数据框

    Issue 我有一个形状文件我已将其导入到 R 中 并为正在进行的分析选择了感兴趣的变量 我的最终目标是插值点数据 海豚 ID 获取海面温度 SST 堆栈中每个单独的光栅文件的值70 栅格来自名为 ncin SST 的对象 该对象是使用函数
  • R tm 包创建 N 个最常见术语的矩阵

    我有一个termDocumentMatrix使用创建的tmR 中的包 我正在尝试创建一个包含 50 个最常出现的术语的矩阵 数据框 当我尝试转换为矩阵时 出现此错误 gt ap m lt as matrix mydata dtm Error
  • R 未获取用户库

    我有一个带 R 3 6 0 的 Fedora 30 系统 用户库设置在Renviron就像这个 R LIBS USER R LIBS USER R x86 64 redhat linux gnu library 3 6 事实上 它出现在交互
  • R中一张图中的多个条形图

    我是 R 初学者 我需要创建一个像这样的图表 https i stack imgur com az56z jpg https i stack imgur com az56z jpg 我不知道如何生成整个数据集 基本思想是某个外显子 ID 会
  • 如何在R中的2行之间交换多个值

    我有一个大小为 10x100 的矩阵 如何交换前 30 列中第 1 行和第 2 行之间的值 我们可以反转前两行的行索引以及通过采取序列创建的列索引rounded 30 总列数用于交换行中的值 colS lt seq round ncol m
  • R 在读取文件时添加额外的数字

    我一直在尝试读取一个包含日期字段和数字字段的文件 我的数据在 Excel 工作表中 如下所示 Date X 1 25 2008 0 0023456 12 23 2008 0 001987 当我在 R 中使用readxl read xlsx函
  • 不理解..密度的行为

    在下面的数据框中 我预计密度的 y 轴值为 0 6 和 0 4 但它们是 1 0 我觉得我使用的方式显然缺少一些非常基本的东西 密度 但是我的大脑冻结了 我将如何使用 密度 获得所需的行为 任何帮助将不胜感激 df lt data fram
  • 递归累积函数

    我需要在 R 中编写一个累积求和函数 但我一直碰壁 该函数具有以下结构 a x1 a x2 a 2 x1 a x3 a 2 x2 a 3 x1 a x4 a 2 x3 a 3 x2 a 4 x1 等等 cumsum 似乎不适用于此类功能 有

随机推荐