data.frame,其中一列包含R中的矩阵

data.frame,其中一列包含R中的矩阵,r,dataframe,R,Dataframe,我试图将一些矩阵放入R中的数据帧中,类似于: m <- matrix(c(1,2,3,4), nrow=2, ncol=2) df <- data.frame(id=1, mat=m) m您得到的结果(2行x 3列)是R的预期结果,因为它相当于cbind一个向量(id,带循环)和一个矩阵(m) 在我看来,如果您确实想绑定不同的数据结构,最好使用列表或数组(当维度一致时,不允许混合使用数值和因子值)。否则,只需cbind将矩阵绑定到现有的data.frame,如果两者具有相同的行数,

我试图将一些矩阵放入R中的数据帧中,类似于:

m <- matrix(c(1,2,3,4), nrow=2, ncol=2)
df <- data.frame(id=1, mat=m)
m您得到的结果(2行x 3列)是R的预期结果,因为它相当于
cbind
一个向量(
id
,带循环)和一个矩阵(
m

在我看来,如果您确实想绑定不同的数据结构,最好使用
列表
数组
(当维度一致时,不允许混合使用数值和因子值)。否则,只需
cbind
将矩阵绑定到现有的data.frame,如果两者具有相同的行数,则执行此操作。比如说

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))
如果您计划使用不同维度的矩阵,并且列表的组织方式(对于行)与外部数据框的组织方式相同,则列表更易于使用。您可以轻松地将其子集。以下是一个例子:

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))

df1我发现包含矩阵的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)

一种更简单的方法是使用矩阵占位符定义数据框

m <- matrix(c(1, 2, 3, 4), nrow = 2, ncol = 2) 
df <- data.frame(id = 1, mat = rep(0, nrow(m)))

我在试图理解pls包中的汽油数据时遇到了同样的问题。用于作业的
$
。 首先,让我们创建一个矩阵,将其称为spectra_mat,然后是一个称为response_var1的向量

spectra_mat = matrix(1:45, 9, 5)
response_var1 = seq(1:9)
现在我们将向量响应_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 ...

包含矩阵列的数据帧在特定场景中确实有其用途。这些场景是数据集中每个观测值都有一个变量的完整向量的情况。我遇到过两种常见的情况:

  • 贝叶斯分析:您为每个观察创建后验预测,因此对于新数据中的每个“行”,您都有一个完整的向量(该向量的长度是MCMC迭代的次数)
  • 功能数据分析:每个“观察”本身就是一个函数,您将观察到的该函数的实现存储为一个向量
  • 如果您使用的是数据帧,那么有几种明显的方法来处理这些数据,它们都是低效的。我将以贝叶斯案例为例:

    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))
    
  • “超宽”格式:除了数据帧的其他列之外,向量的每个元素都有一列。这就形成了一个非常宽的数据帧,通常很难使用它。这也使得仅提及与后壁相对应的柱体变得困难
  • “超长”(整洁)格式:非常占用内存,因为数据帧的所有其他列都必须在每次迭代后不必要地重复
  • 列表列:您可以创建一个列表,其中每个元素都是对应于该数据帧行的后面的向量。这里的问题是,您想要执行的大多数操作都需要将后面的列表取消列出到矩阵中,并且列出/取消列出是不必要的计算
  • 对于这种情况,带有矩阵列的数据帧是非常有用的解决方案。后验数据保留在与数据帧具有相同行数的矩阵中。但该矩阵在数据帧中仅被识别为单个“列”,使用df$mat引用该列将返回该矩阵。您甚至可以使用一些dplyr函数(如筛选)返回矩阵的相应行,但这有点困难

    创建矩阵列的最简单方法分为两步。首先创建不带矩阵列的数据框,然后添加带有简单赋值的矩阵列。我还没有找到一个不涉及改变列类型的
    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
    

    m尽管我给出了答案,但我还是对另一位受访者表示同情:你为什么要这么做?也许我们可以帮你找到一个更好的R习惯用法…我有输入和输出为矩阵的数据。我希望每一次体验都是一行数据帧。tidyverse系列软件包的最新进展,特别是purrr,使得为函数式编程创建任意数据类型的嵌套列非常有用。嵌套的矩阵列可以用作将每个矩阵转换为更简单结构的准备步骤。尽管这样可以将矩阵转换为数据帧中的列。对于某些应用程序来说可能还可以(您可以通过i*nrow+ncol访问元素),但如果您的矩阵大小不同,则会受到限制。有关更简单的解决方案,请参阅我的答复。
    
    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 ...
    
    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