从大型数据集的数据框有效地创建矩阵

Posted

技术标签:

【中文标题】从大型数据集的数据框有效地创建矩阵【英文标题】:Effectively Create a Matrix from a Dataframe for Large dataset 【发布时间】:2018-10-11 16:35:03 【问题描述】:

我正在尝试从大型数据框创建矩阵。这是一个示例数据框

df <- data.frame(index=c("x","y","j","ww","rr","ff"),
             a=c(1,3,3,5,1,6), 
             b=c(2,3,5,3,2,3),
             c=c(3,2,4,5,6,10),
             d =c("ha1","ha2","ha3","ha4","ha5","ha"))

> df
  index a b  c   d
1     x 1 2  3 ha1
2     y 3 3  2 ha2
3     j 3 5  4 ha3
4    ww 5 3  5 ha4
5    rr 1 2  6 ha5
6    ff 6 3 10  ha

矩阵需要看起来像这样。

> matrix
   a b  c
ff 6 3 10
j  3 5  4
rr 1 2  6
ww 5 3  5
x  1 2  3
y  3 3  2

所以,我使用的方法是首先使用 melt 将数据帧结构更改为类似的结构

df1 <- reshape2::melt(data = df, id.vars = c("index","d"), variable.name = "colname", value.name = "value")

> df1
   index   d colname value
1      x ha1       a     1
2      y ha2       a     3
3      j ha3       a     3
4     ww ha4       a     5
5     rr ha5       a     1
6     ff  ha       a     6
7      x ha1       b     2
8      y ha2       b     3
9      j ha3       b     5
10    ww ha4       b     3
11    rr ha5       b     2
12    ff  ha       b     3
13     x ha1       c     3
14     y ha2       c     2
15     j ha3       c     4
16    ww ha4       c     5
17    rr ha5       c     6
18    ff  ha       c    10

然后做acast

matrix <- acast(df1, index~colname, value.var="value")

上述方法有效,但现在我正在处理大数据集,当使用熔化 (df1) 转换数据时,它变得非常大并崩溃。

那么有什么方法可以有效地从数据帧 df 创建矩阵,甚至不需要中间步骤。

【问题讨论】:

这不是删除第一列,使用as.matrix 转换为矩阵并将行名更改为第一列吗?即'row.names&lt;-'(as.matrix(df[-1]), df[,1]) 是否有逻辑为什么在预期输出中更改行顺序 【参考方案1】:

根据输出,我们可以删除第一列 character 列,将数据集的其余部分转换为 matrix 并为第一列分配行名

m1 <- `row.names<-`(as.matrix(df[-1]), df[,1])
str(m1)
# num [1:2, 1:3] 1 3 2 3 3 2
# - attr(*, "dimnames")=List of 2
#  ..$ : chr [1:2] "x" "y"
#  ..$ : chr [1:3] "a" "b" "c"
m1
#  a b c
#x 1 2 3
#y 3 3 2

如果我们使用tidyverse,那么column_to_rownames 是有用的

library(tidyverse)
column_to_rownames(df, "x") %>%
      as.matrix

更新

基于更新的数据集,我们可以在对数值列进行子集化后应用相同的逻辑

`row.names<-`(as.matrix(df[2:4]), df[,1])

如果numeric列多,获取索引困难,则遍历列获取数字列的索引,并将其用于子集

m2 <- `row.names<-`(df[sapply(df, is.numeric)], df[,1])[order(df[,1]),]
m2
#   a b  c
#ff 6 3 10
#j  3 5  4
#rr 1 2  6
#ww 5 3  5
#x  1 2  3
#y  3 3  2

【讨论】:

感谢您的参与。但这是一个非常简单的示例,我还有更多专栏。 @JohnG 当你展示一个简单的例子时还不清楚。你能用一个更复杂的例子来更新你的锅吗? @JohnG 如果我是对的,它只需要对列进行子集化'row.names&lt;-'(as.matrix(df[2:4]), df[,1]) 知道了。主要的是我需要控制行名和列名..例如使用 acast acast(df1, index~colname, value.var="value") ,“索引”将是我的行名和“列名”将是我的列名.. @JohnG 我理解你的意思,但我认为如果最终目标是拥有一个包含一些选定列的矩阵,那么执行melt 后跟cast 会效率低下跨度>

以上是关于从大型数据集的数据框有效地创建矩阵的主要内容,如果未能解决你的问题,请参考以下文章

R中向具有大量数据集的数据框添加新列的有效方法

在 phpMyAdmin SQL 表中存储大型数据集的有效方法

基于多个字段搜索大型数据集的有效方法

在 Javascript 中有效地逐步过滤大型数据集

在 R 中拆分大型数据集的有效方法

(预)处理存储在 json 中的大型数据集的最有效方法是啥?