【问题标题】:Sparse matrix from list in RR中列表中的稀疏矩阵
【发布时间】:2023-03-19 14:04:01
【问题描述】:

您好,我有一个结构如下的文件:

    > df
    LATITUDE1 LONGITUDE1 LATITUDE2 LONGITUDE2   X   V    Y   W  Cell1  Cell2
1      -71.2       -180   -71.344     178.97 -72 -72 -180 178 -26100 -25742
2      -71.0       -180   -71.300     177.70 -71 -72 -180 177 -25740 -25743
3      -70.8       -180   -71.300     177.70 -71 -72 -180 177 -25740 -25743
4      -70.6       -180   -71.444     174.30 -71 -72 -180 174 -25740 -25746
5      -70.4       -180   -71.040     175.76 -71 -72 -180 175 -25740 -25745
6      -70.2       -180   -70.499     176.33 -71 -71 -180 176 -25740 -25384
7      -70.0       -180   -70.350     177.03 -70 -71 -180 177 -25380 -25383
8      -69.8       -180   -70.995     176.40 -70 -71 -180 176 -25380 -25384
9      -69.6       -180   -71.309     171.87 -70 -72 -180 171 -25380 -25749
10     -69.4       -180   -71.015     171.42 -70 -72 -180 171 -25380 -25749

我有一些 R 代码总结了从 Cell1-levels 到 Cell2-levels 的非零转换概率:

counts <- by(df, df$Cell1, function(d) c(table(d$Cell2)/nrow(d)))

> counts1
df$Cell1: -26100
-25742 -25743 -25746 -25745 -25384 -25383 -25749 
     1      0      0      0      0      0      0 
------------------------------------------------------------ 
df$Cell1: -25740
-25742 -25743 -25746 -25745 -25384 -25383 -25749 
   0.0    0.4    0.2    0.2    0.2    0.0    0.0 
------------------------------------------------------------ 
df$Cell1: -25380
-25742 -25743 -25746 -25745 -25384 -25383 -25749 
  0.00   0.00   0.00   0.00   0.25   0.25   0.50 

我希望能够从这个列表(零和非零)中创建一个转换概率的稀疏矩阵:由于我的列表元素长度不等,这相当困难。我试过do.call,但这是不可接受的,因为我必须“手动”查找每个单元级别并确定它是否应该为零。

> do.call(rbind, counts)
-25746 -25745 -25743 -25384
-26100    1.0   1.00   1.00    1.0
-25740    0.2   0.20   0.40    0.2
-25380    0.5   0.25   0.25    0.5

谢谢。

编辑:使用下面的 akrins 代码,我得到了一个矩阵形式

do.call(rbind, counts)
       -25742 -25743 -25746 -25745 -25384 -25383 -25749
-26100      1    0.0    0.0    0.0   0.00   0.00    0.0
-25740      0    0.4    0.2    0.2   0.20   0.00    0.0
-25380      0    0.0    0.0    0.0   0.25   0.25    0.5

我期待表单的结果

    A    B    C    D
A  aa    0   ac    0
B  ba   bb    0   bd
C   0   cb    0    0
D   0   db    0    0

【问题讨论】:

  • 我猜你可能需要table(factor(d$Cell2, levels=unique(ofes.df$Cell2)) 里面的by
  • 谢谢您,您的代码已经完成了一些工作。现在,由此产生的矩阵不是在行和列中具有相同“状态”的方阵。我们也可以解决这个问题吗?
  • 你需要展示一个给出非方阵的例子。使用这个例子,我得到了方形
  • 我刚刚意识到我改变了我的网格大小并且由此产生的单元格级别是不同的。但是您可以从表面上看待编辑过的问题。一般来说,我们会有一个非方阵。而且两边的状态也不一样。
  • 能不能把预期的结果也显示出来,方便别人查看?

标签: r list matrix statistics sparse-matrix


【解决方案1】:

表格函数在给定因子时为每个级别创建一个条目。

如果我理解正确,这就是你想要的:

df <- read.table(text="    LATITUDE1 LONGITUDE1 LATITUDE2 LONGITUDE2   X   V    Y   W  Cell1  Cell2
1      -71.2       -180   -71.344     178.97 -72 -72 -180 178 -26100 -25742
2      -71.0       -180   -71.300     177.70 -71 -72 -180 177 -25740 -25743
3      -70.8       -180   -71.300     177.70 -71 -72 -180 177 -25740 -25743
4      -70.6       -180   -71.444     174.30 -71 -72 -180 174 -25740 -25746
5      -70.4       -180   -71.040     175.76 -71 -72 -180 175 -25740 -25745
6      -70.2       -180   -70.499     176.33 -71 -71 -180 176 -25740 -25384
7      -70.0       -180   -70.350     177.03 -70 -71 -180 177 -25380 -25383
8      -69.8       -180   -70.995     176.40 -70 -71 -180 176 -25380 -25384
9      -69.6       -180   -71.309     171.87 -70 -72 -180 171 -25380 -25749
10     -69.4       -180   -71.015     171.42 -70 -72 -180 171 -25380 -25749")

levels <- unique(c(df$Cell1, df$Cell2))
df$Cell1 <- factor(df$Cell1, levels=levels)
df$Cell2 <- factor(df$Cell2, levels=levels)
t <- table(df$Cell1, df$Cell2)

require("Matrix")
mat <- Matrix(t, sparse=T)

这会产生:

>t

         -26100 -25740 -25380 -25742 -25743 -25746 -25745 -25384 -25383 -25749
  -26100      0      0      0      1      0      0      0      0      0      0
  -25740      0      0      0      0      2      1      1      1      0      0
  -25380      0      0      0      0      0      0      0      1      1      2
  -25742      0      0      0      0      0      0      0      0      0      0
  -25743      0      0      0      0      0      0      0      0      0      0
  -25746      0      0      0      0      0      0      0      0      0      0
  -25745      0      0      0      0      0      0      0      0      0      0
  -25384      0      0      0      0      0      0      0      0      0      0
  -25383      0      0      0      0      0      0      0      0      0      0
  -25749      0      0      0      0      0      0      0      0      0      0

如果您知道单元格位于例如-30000 和 30000 你可以简单地设置levels=-30000:30000

编辑: 如果您想要概率,只需对线条进行规范化或使用 prop.table 即可。

t <- prop.table(table(df$Cell1, df$Cell2), margin=1)

但是你最终在没有条目的行上得到 NaN。您应该自己规范线条,或者如果您更喜欢快速而肮脏的方式,t[is.nan(t)] &lt;- 0

所以你最终得到:

> mat
10 x 10 sparse Matrix of class "dtCMatrix"
   [[ suppressing 10 column names ‘-26100’, ‘-25740’, ‘-25380’ ... ]]

-26100 . . . 1 .   .   .   .    .    .  
-25740 . . . . 0.4 0.2 0.2 0.20 .    .  
-25380 . . . . .   .   .   0.25 0.25 0.5
-25742 . . . . .   .   .   .    .    .  
-25743 . . . . .   .   .   .    .    .  
-25746 . . . . .   .   .   .    .    .  
-25745 . . . . .   .   .   .    .    .  
-25384 . . . . .   .   .   .    .    .  
-25383 . . . . .   .   .   .    .    .  
-25749 . . . . .   .   .   .    .    . 

【讨论】:

  • 这似乎可以解决问题。不过,我在稀疏矩阵中得到了很多 NaN
  • 谢谢。 prop.table 对于我的数据集来说相当慢,因为我的表的尺寸是 50,000 x 50,000。我能以某种方式加快速度吗?
  • 查看this post,所说的也适用于逐行规范化。例如,您只需在扫描中将 2 替换为 1,或者在左侧而不是右侧乘以 diag(1/colSums(mat))。我认为后者会特别有效,特别是因为您可以通过将 doDiag 参数设置为 TRUE 来使用 matrix 包创建稀疏对角矩阵。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 2015-07-24
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多