【问题标题】:Converting contingency tables with counts to two-column data tables with frequency columns将具有计数的列联表转换为具有频率列的两列数据表
【发布时间】:2019-02-16 20:42:09
【问题描述】:

我想在 R data.table 中输入频率表。

数据格式如下:

          Height
Gender    3      35
m       173     125
f       323     198

...其中表中的条目(173、125 等)是计数。

我有一个 2 x 2 表,我想把它变成两列 data.table

数据来自对在高处筑巢的鸟类的研究。问题是不同性别的鸟是否喜欢特定的高度。

我认为频率表应该变成这样的:

    Gender height   N
      m      3     173
      m      35    125
      f      3     323
      f      35    198

但现在我不太确定。我想运行的一些模型需要逐项列出每个案例。

我可以在 R 中进行这种转换吗?理想情况下,我想要一种在两种格式之间来回切换的方法。

【问题讨论】:

  • 你能显示输入的样子吗?在问题的最后分享dput(input_table)的输出。
  • 我还没有真正制作过数据表,除了我上面描述的那个:structure(list(sex = c("f", "f", "m", "m"), height = c(3, 35, 3, 35), freq = c(323, 198, 173, 125)), class = "data.frame", row.names = c(NA, -4L))
  • 顺便说一句,我故意使用 data.table,因为本书的其他部分需要它。
  • 您在问题中发布的是您想要的输出,不是吗?我要的是你提到的“2 by 2 table”。

标签: r data.table


【解决方案1】:

基于对 ?table 的评论。

  1. 制作一个数据框 (x),其中包含 Gender、Height 和 Freq 列,这将是您的 N 值。

  2. 使用将其转换为表格

tabledata <- xtabs(Freq ~ ., x)

有许多基本函数可以处理这种数据,这显然比单独的行要紧凑得多。

同样来自 ?loglin this example using table。

 loglin(HairEyeColor, list(c(1, 2), c(1, 3), c(2, 3)))

【讨论】:

  • 相当优雅,那个。我很容易生成```> tabledata HEIGHT GENDER 3 35 f 323 198 m 173 125```
  • 我很想更正上面的评论,但我已经没有权限了。我想说的是---------> 相当优雅,xtabs。我很容易就能生成一个完美的 2 x 2 表。我把这个放在工具箱里。 loglin 仍然在挑战我,但我仍然不是 100% 知道为什么我需要这么重的统计锤。我想看看这两个身高是否存在性别差异,这感觉就像是香草 ?² 分析。我会考虑更多。
  • 您可以通过对表格对象执行 summary() 来获得卡方。
【解决方案2】:

谢谢大家(@simon 和@Elin)的帮助。我以为我正在进行一项民意调查,会得到诸如“从 4 行版本开始”或“从 719 行版本开始”之类的答案,你们都给了我一个完整的工具箱,其中包含从一个到另一个的方法。它真的很棒,内容丰富,而且远远超过调查应得的。

毫无疑问,我需要更加努力地工作,更明确地提出问题。我看到这个 boondoggle 获得的 -3 评级,明确了我没有向知识库添加任何内容的事实,因此将删除该问题以防止未来的搜索者找到这个问题。最近我的问题表现不佳,作为当年的前任教师、五本书的作者和统计学博士,我在 Stack Exchange 待了这么久,并站在这里与一个声望点。一。这意味着我对你的回答的赞成票不算数。

那个声望点应该是猩红色的。


这就是我的意思: 在书中,表达数据的常用方法是使用 2×2 表:

             Height 
 Gender     3     35 
    M      173   175 
    F      323   198 

我的 tic-tac-sized 思维看到了两种将其输入数据表的方法:

require(data.table)
GENDER <- c("m","m","f","f")
HEIGHT <- c(3, 35, 3, 35)
N <- c(173, 125, 323, 198)
SANDFLIERS <-data.table(GENDER, HEIGHT, N)

这给出了数据的四行平面文件/整洁表示:

   GENDER HEIGHT   N
1:      m      3 173
2:      m     35 125
3:      f      3 323
4:      f     35 198

另一种选择是制作一个 719 行的数据表,其中包含 173 个男性@3 英尺、125 个男性@35 英尺等。如果您使用 rep() 命令并仔细构建表列,这还不错。我讨厌做算术,所以我把其中一些数字留了下来。

# I need 173+125 males, and 323+198 females.
# One c(rep()) for "m", one c(rep() for "f", and one c() to merge them
gender <- c(c(rep("m", 173+25)), c(rep("f",(323+198))))

# Same here, except the c() functions are one level 'deeper'. I need two
# sets for males (at heights 3 and 35, 173 and 125 of each, respectively)
# and two sets for females (at heights 3 and 35, 323 and 198 respectively)
heights <-c(c(c(rep(3, 173)), c(rep(35,25))), c(c(rep(3, 323)), c(rep(35,198))))

当合并到 data.table 中时,会给出 719 行,每只观察到的鸟都有一个。

  1:      m       3
  2:      m       3
  3:      m       3
  4:      m       3
  5:      m       3
 ---               
715:      f      35
716:      f      35
717:      f      35
718:      f      35
719:      f      35

现在我有了两种格式的数据,我开始寻找进行绘图和分析的方法。

我可以使用719行的版本获得马赛克图,但是由于我的1点声誉,您看不到它

mosaicplot(table(sandfliers), COLOR=TRUE, margin, legend=TRUE)

Mosaic Plot

您可以使用 4 行版本获得气球图

Balloon Plot

所以我的问题是,对于那些在这类事情上有很多经验的人来说,你觉得 4 行或 719 行的桌子更常见吗?我可以从一个更改到另一个,但要添加到书中的代码更多(我再次听到我的编辑,“你在教统计,而不是 R”)。

所以,正如我在顶部所说的,这只是一个非正式的民意调查,关于一个是否比另一个更经常使用,或者初学者是否更适合使用一个。

【讨论】:

  • 没有必要尴尬。我认识很多统计学家,他们是各方面的专家,但不是 R。就我自己而言,我对编程的了解肯定比对统计学的了解更多。然而,当我在学习 R 时(甚至现在,有时也是如此),我发现将数据从我拥有的形式有效地处理为库函数所需的形式比使用函数本身要困难得多。我很乐意将您的问题编辑成我认为大多数回答者都希望的形式,如果您愿意,我会为您的问题“+1”。
  • 每一点都有帮助。谢谢,@Simon。
  • 我希望你能看到这个答案的后半部分。我添加它是为了解释我的想法。
  • 我已尝试编辑您的问题以使其具体到足以回答。我希望您寻求“非正式民意调查”的附加问题是否使用一种格式而不是另一种格式可能会因寻求意见而不是确定的事实答案而被投票关闭。能够非常轻松地来回转换格式意味着您可以适应您想要使用的任何模型或公式所需的任何数据格式。
  • 我对这个确切的问题想了很多。如果您查看默认 r 附带的示例数据,您会看到许多表格对象。这些有时被称为专有格式的立方体。这一切都很好,但是如果我们有一个包含 40 个变量的实际调查,一些数字,一些因素。创建交叉表来存储它是否有意义?显然,在大小/内存方面存在一个临界点。但这实际上取决于您有多少相同的观察结果
【解决方案3】:

这是列联表的形式。直接进入R并不容易,但可以按如下方式完成(基于http://cyclismo.org/tutorial/R/tables.html):

> f <- matrix(c(173,125,323,198),nrow=2,byrow=TRUE)
> colnames(f) <- c(3,35)
> rownames(f) <- c("m","f")
> f <- as.table(f)
> f
    3  35
m 173 125
f 323 198

然后您可以使用以下方法创建计数或频率表:

> as.data.frame(f)
  Var1 Var2 Freq
1    m    3  173
2    f    3  323
3    m   35  125
4    f   35  198

R Cookbook 提供了一个简短的函数来转换为案例表(即单个项目的长列表),如下所示:

> countsToCases(as.data.frame(f))

...在哪里:

# Convert from data frame of counts to data frame of cases.
# `countcol` is the name of the column containing the counts
countsToCases <- function(x, countcol = "Freq") {
    # Get the row indices to pull from x
    idx <- rep.int(seq_len(nrow(x)), x[[countcol]])

    # Drop count column
    x[[countcol]] <- NULL

    # Get the rows from x
    x[idx, ]
}

...因此您可以将数据从任何起始格式转换为任何分析方法所需的格式。

(编辑)

另一种阅读列联表的方法是从如下文本开始:

> ss <- " 3      35
+ m       173     125
+ f       323     198"
> read.table(text=ss,row.name=1)
   X3 X35
m 173 125
f 323 198

除了使用text =,您还可以使用文件名从(例如)CSV 文件中读取表格。

【讨论】:

  • 是的,完全正确。我从你展示的表格开始。关于如何将其输入 R,我有两种选择:我在问题中显示的 4 行方式,以及您在上面显示的非常长的表格。我知道两者都可以制造,一个可以变成另一个。我不知道的是给读者的建议。如果我要进行比较 m 高度和 f 高度的 t 检验,那么从 data.table 开始的最佳方法是什么?我查看了很多进行我想要的测试的包,但没有提到频率变量,所以我认为以长格式输入数据可能会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 2021-11-17
  • 2015-11-25
  • 2012-01-28
相关资源
最近更新 更多