Flat table 具有标识值
Flat table with identity values
我有这个整洁的数据框:
mydf <- expand.grid(
A = letters[1:3],
B = letters[4:5],
C = letters[6:7],
stringsAsFactors = FALSE
)
mydf$D = runif(nrow(mydf))
我想让它像 myft <- ftable(mydf, row.vars = 1, col.vars = 2:3)
一样平坦 table,但我不想有意外事件 table,而是想要列 D
的相应值].
我尝试使用 myft[] <- mydf$D
,这样更好,但值顺序不正确。如何匹配相同的顺序(即 D
的值对应于参数 A
、B
和 C
的值)?
myarray <- xtabs(D ~ A + B + C, data = mydf)
ftable(myarray, row.vars = 1, col.vars = 2:3)
我理解你的问题特别要求 ftable
,但你可能会发现简单地使用一些用于重塑数据的更常见的函数更直接。
这里,例如 dcast
from "data.table":
library(data.table)
dcast(as.data.table(mydf), A ~ ..., value.var = "D")
## A d_f d_g e_f e_g
## 1: a 0.2655087 0.9446753 0.9082078 0.06178627
## 2: b 0.3721239 0.6607978 0.2016819 0.20597457
## 3: c 0.5728534 0.6291140 0.8983897 0.17655675
这是 "tidyverse" 方法:
library(tidyverse)
mydf %>%
unite(var, B, C) %>%
spread(var, D)
## A d_f d_g e_f e_g
## 1 a 0.2655087 0.9446753 0.9082078 0.06178627
## 2 b 0.3721239 0.6607978 0.2016819 0.20597457
## 3 c 0.5728534 0.6291140 0.8983897 0.17655675
我之所以推荐这种格式,是因为这些格式更容易通过 predictable 列名称进行索引和引用。在 ftable
中,您实际上没有 dimnames
,而是 "col.vars" 和 "row.vars",它们访问起来不太方便。因此,您不能做 data.frame(myft)
甚至 as.data.frame.matrix(myft)
之类的事情并保持重塑 table.
的形状
要回答您尝试 myft[] <- ...
时有关如何匹配变量顺序的问题,您可以尝试以下操作:
- 在这种情况下,根据因子列(A、B 和 C)对 "D" 的值重新排序。
- 将其转换为逐行矩阵。您应该能够轻松计算出数据所需的行数。
- 使用该矩阵作为替换值。
示例:
myft[] <- matrix(mydf$D[with(mydf, do.call(order, list(A, B, C)))],
nrow = length(unique(mydf$A)), byrow = TRUE)
myft
# B d e
# C f g f g
# A
# a 0.26550866 0.94467527 0.90820779 0.06178627
# b 0.37212390 0.66079779 0.20168193 0.20597457
# c 0.57285336 0.62911404 0.89838968 0.17655675
我有这个整洁的数据框:
mydf <- expand.grid(
A = letters[1:3],
B = letters[4:5],
C = letters[6:7],
stringsAsFactors = FALSE
)
mydf$D = runif(nrow(mydf))
我想让它像 myft <- ftable(mydf, row.vars = 1, col.vars = 2:3)
一样平坦 table,但我不想有意外事件 table,而是想要列 D
的相应值].
我尝试使用 myft[] <- mydf$D
,这样更好,但值顺序不正确。如何匹配相同的顺序(即 D
的值对应于参数 A
、B
和 C
的值)?
myarray <- xtabs(D ~ A + B + C, data = mydf)
ftable(myarray, row.vars = 1, col.vars = 2:3)
我理解你的问题特别要求 ftable
,但你可能会发现简单地使用一些用于重塑数据的更常见的函数更直接。
这里,例如 dcast
from "data.table":
library(data.table)
dcast(as.data.table(mydf), A ~ ..., value.var = "D")
## A d_f d_g e_f e_g
## 1: a 0.2655087 0.9446753 0.9082078 0.06178627
## 2: b 0.3721239 0.6607978 0.2016819 0.20597457
## 3: c 0.5728534 0.6291140 0.8983897 0.17655675
这是 "tidyverse" 方法:
library(tidyverse)
mydf %>%
unite(var, B, C) %>%
spread(var, D)
## A d_f d_g e_f e_g
## 1 a 0.2655087 0.9446753 0.9082078 0.06178627
## 2 b 0.3721239 0.6607978 0.2016819 0.20597457
## 3 c 0.5728534 0.6291140 0.8983897 0.17655675
我之所以推荐这种格式,是因为这些格式更容易通过 predictable 列名称进行索引和引用。在 ftable
中,您实际上没有 dimnames
,而是 "col.vars" 和 "row.vars",它们访问起来不太方便。因此,您不能做 data.frame(myft)
甚至 as.data.frame.matrix(myft)
之类的事情并保持重塑 table.
要回答您尝试 myft[] <- ...
时有关如何匹配变量顺序的问题,您可以尝试以下操作:
- 在这种情况下,根据因子列(A、B 和 C)对 "D" 的值重新排序。
- 将其转换为逐行矩阵。您应该能够轻松计算出数据所需的行数。
- 使用该矩阵作为替换值。
示例:
myft[] <- matrix(mydf$D[with(mydf, do.call(order, list(A, B, C)))],
nrow = length(unique(mydf$A)), byrow = TRUE)
myft
# B d e
# C f g f g
# A
# a 0.26550866 0.94467527 0.90820779 0.06178627
# b 0.37212390 0.66079779 0.20168193 0.20597457
# c 0.57285336 0.62911404 0.89838968 0.17655675