我正在尝试将一些矩阵放在R中的数据框中,例如:
m <- matrix(c(1,2,3,4), nrow=2, ncol=2)
df <- data.frame(id=1, mat=m)
但是当我这样做时,我会得到一个包含2行3列的数据帧,而不是1行2列的数据帧。
阅读文档,我必须使用I()来转义矩阵。
df <- data.frame(id=1, mat=I(m))
str(df)
'data.frame': 2 obs. of 2 variables:
$ id : num 1 1
$ mat: AsIs [1:2, 1:2] 1 2 3 4
据我了解,数据框对于矩阵的每一行包含一行,而mat字段是矩阵列值的列表。
因此,我如何获得包含矩阵的数据帧?
谢谢!
答案 0 :(得分:5)
我发现包含矩阵的data.frames令人费解,但是:我知道实现这一目标的唯一方法隐藏在stats:::simulate.lm
试试这个,捅一下,看看发生了什么:
d <- data.frame(y=1:5,n=5)
g0 <- glm(cbind(y,n-y)~1,data=d,family=binomial)
debug(stats:::simulate.lm)
s <- simulate(g0,n=5)
这是一种奇怪的后门解决方案。创建一个列表,将其类更改为data.frame
,然后(这是必需)手动设置names
和row.names
(如果您不这样做)数据仍将在对象中的最后步骤,但它将打印出来,好像它有零行......)
m1 <- matrix(1:10,ncol=2)
m2 <- matrix(5:14,ncol=2)
dd <- list(m1,m2)
class(dd) <- "data.frame"
names(dd) <- LETTERS[1:2]
row.names(dd) <- 1:5
dd
答案 1 :(得分:4)
更简单的方法是使用矩阵
的占位符定义数据框m <- matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2)
df <- data.frame(id = 1, mat = rep(0, nrow(m)))
然后分配矩阵。无需使用列表类或使用*apply()
函数。
df$mat <- m
答案 2 :(得分:2)
我在尝试理解 pls 包中的汽油数据时遇到了同样的问题。使用$
作业。
首先,让我们创建一个矩阵,让我们称之为spectra_mat,然后称为response_var1。
spectra_mat = matrix(1:45, 9, 5)
response_var1 = seq(1:9)
现在我们将向量response_var1放在一个新的数据框中 - 让我们称之为df。
df = data.frame(response_var1)
df$spectra = spectra_mat
要检查,
str(df)
'data.frame': 9 obs. of 2 variables:
$ response_var1: int 1 2 3 4 5 6 7 8 9
$ spectra : int [1:9, 1:5] 1 2 3 4 5 6 7 8 9 10 ...
答案 3 :(得分:1)
您获得的结果(2行x 3列)是R的预期结果,因为它等于cbind
向量(id
,带有回收)和矩阵({{ 1}})。
IMO,如果您真的想要绑定不同的数据结构,最好使用m
或list
(当维度一致时,不允许混合使用数值和因子值)。否则,只有array
矩阵到现有data.frame(如果两者具有相同的行数)才能完成工作。例如
cbind
,结果显示
x1 <- replicate(2, rnorm(10))
x2 <- replicate(2, rnorm(10))
x12l <- list(x1=x1, x2=x2)
x12a <- array(rbind(x1, x2), dim=c(10,2,2))
如果您计划使用不同维度的矩阵,并且提供它们以与外部数据相同的方式(对于行)进行组织,则可以更轻松地使用列表。您可以轻松地对它们进行子集化。这是一个例子:
> str(x12l)
List of 2
$ x1: num [1:10, 1:2] -0.326 0.552 -0.675 0.214 0.311 ...
$ x2: num [1:10, 1:2] -0.164 0.709 -0.268 -1.464 0.744 ...
> str(x12a)
num [1:10, 1:2, 1:2] -0.326 0.552 -0.675 0.214 0.311 ...
您还可以使用df1 <- data.frame(grp=gl(2, 5, labels=LETTERS[1:2]),
age=sample(seq(25,35), 10, rep=T))
with(df1, tapply(x12l$x1[,1], list(grp, age), mean))
(用于列表)和lapply
(用于数组)函数。
答案 4 :(得分:1)
包含矩阵列的数据框确实在特殊情况下使用。在这些情况下,数据集中的每个观测值都有一个带有某个变量的整个向量。我遇到过两种常见的情况:
如果您正在使用数据帧,则有几种显而易见的方法来处理这些数据,但效率均很低。我将以贝叶斯案例为例:
带有矩阵列的数据框对于这种情况非常有用。后验方保持在矩阵中,该矩阵具有与数据帧相同的行数。但是该矩阵仅在数据帧中被识别为单个“列”,并且使用df $ mat引用该列将返回该矩阵。您甚至可以使用一些dplyr函数(例如过滤)来返回矩阵的相应行,但这有点experimental。
创建矩阵列的最简单方法是两步。首先创建不带矩阵列的数据框,然后通过简单的分配添加矩阵列。我还没有找到一种不涉及I()
即可更改列类型的一站式解决方案。
m <- matrix(c(1,2,3,4), nrow=2, ncol=2)
df <- data.frame(id = rep(1, nrow(m)))
df$mat <- m
names(df)
# [1] "id" "mat"
str(df)
# 'data.frame': 2 obs. of 2 variables:
# $ id : num 1 1
# $ mat: num [1:2, 1:2] 1 2 3 4