6.19 数据框与列联表互换

6.19.1 问题

你想要在多种情况的一个数据框、每种情况类型计数的数据框以及一个列联表之间转换。

6.19.2 方案

这里有 3 种数据结构代表相同的信息,但是形式不同:

  • cases: 每一行代表一个情况的数据框
  • ctable: 一个列联表
  • counts: 计数的数据框,每行代表每一种组合的数目
  1. # 每一行代表一种情况
  2. cases <- data.frame(Sex = c("M", "M", "F", "F", "F"), Color = c("brown",
  3. "blue", "brown", "brown", "brown"))
  4. cases
  5. #> Sex Color
  6. #> 1 M brown
  7. #> 2 M blue
  8. #> 3 F brown
  9. #> 4 F brown
  10. #> 5 F brown
  11. # 一个列联表
  12. ctable <- table(cases)
  13. ctable
  14. #> Color
  15. #> Sex blue brown
  16. #> F 0 3
  17. #> M 1 1
  18. # 一个每种组合计数的表格
  19. counts <- data.frame(Sex = c("F", "M", "F", "M"), Color = c("blue",
  20. "blue", "brown", "brown"), Freq = c(0, 1, 3, 1))
  21. counts
  22. #> Sex Color Freq
  23. #> 1 F blue 0
  24. #> 2 M blue 1
  25. #> 3 F brown 3
  26. #> 4 M brown 1

6.19.2.1 将情况记录转为列联表

将情况记录转为列联表(上面已经展示了):

  1. ctable <- table(cases)
  2. ctable
  3. #> Color
  4. #> Sex blue brown
  5. #> F 0 3
  6. #> M 1 1
  7. # 如果你使用两个向量调用table函数,它将不会给维度添加名字(Sex和Color)
  8. table(cases$Sex, cases$Color)
  9. #>
  10. #> blue brown
  11. #> F 0 3
  12. #> M 1 1
  13. # 维度名可以通过`dnn`选项手动指定
  14. table(cases$Sex, cases$Color, dnn = c("Sex", "Color"))
  15. #> Color
  16. #> Sex blue brown
  17. #> F 0 3
  18. #> M 1 1

6.19.2.2 将情况记录转为计数

它可以用一个数据框代表每一种组合的计数。注意它被转换并存储在 countdf 对象中:

  1. # Cases to Counts
  2. countdf <- as.data.frame(table(cases))
  3. countdf
  4. #> Sex Color Freq
  5. #> 1 F blue 0
  6. #> 2 M blue 1
  7. #> 3 F brown 3
  8. #> 4 M brown 1

6.19.2.3 countsToCases() 函数

这个函数使用在上面的例子中:

  1. # Convert from data frame of counts to data frame of
  2. # cases. `countcol` is the name of the column
  3. # containing the counts
  4. countsToCases <- function(x, countcol = "Freq") {
  5. # Get the row indices to pull from x
  6. idx <- rep.int(seq_len(nrow(x)), x[[countcol]])
  7. # Drop count column
  8. x[[countcol]] <- NULL
  9. # Get the rows from x
  10. x[idx, ]
  11. }

6.19.2.4 列联表转为情况记录

  1. countsToCases(as.data.frame(ctable))
  2. #> Sex Color
  3. #> 2 M blue
  4. #> 3 F brown
  5. #> 3.1 F brown
  6. #> 3.2 F brown
  7. #> 4 M brown

注意,countsToCases() 函数定义在上面。

6.19.2.5 列联表转为计数

  1. as.data.frame(ctable)
  2. #> Sex Color Freq
  3. #> 1 F blue 0
  4. #> 2 M blue 1
  5. #> 3 F brown 3
  6. #> 4 M brown 1

从这里我们可以看到上一个代码的中间效果

6.19.2.6 计数转为情况记录

  1. countsToCases(countdf)
  2. #> Sex Color
  3. #> 2 M blue
  4. #> 3 F brown
  5. #> 3.1 F brown
  6. #> 3.2 F brown
  7. #> 4 M brown

这相当于是列联表转为情况记录的第二步。

6.19.2.7 计数转为列联表

  1. xtabs(Freq ~ Sex + Color, data = countdf)
  2. #> Color
  3. #> Sex blue brown
  4. #> F 0 3
  5. #> M 1 1