【问题标题】:Dividing matrices with unequal dimensions in r在r中划分具有不等维度的矩阵
【发布时间】:2022-01-11 21:50:38
【问题描述】:

我有一个过滤到一个月的数据集。我还有一个矩阵列表 (l1),它与数据帧列表 (int1) 的长度相同。列表中的矩阵具有不同的尺寸(例如,3x3、2x2)。

设置数据和列表:

library(lubridate)
library(tidyverse)
library(purrr)

date <- rep_len(seq(dmy("26-12-2010"), dmy("13-07-2011"), by = "days"), 200)
ID <- rep(c("A","B"), 100)
df <- data.frame(date = date,
                 x = runif(length(date), min = 60000, max = 80000),
                 y = runif(length(date), min = 800000, max = 900000),
                 ID)

df$jDate <- julian(as.Date(df$date), origin = as.Date('1970-01-01'))
df$Month <- month(df$date)

# First 10-day interval for `A`
t1 <- c(100,150,200)
# Second 10-day interval for `A`
t2 <- c(200,250,350)
# Third 10-day interval for `A`
t3 <- c(300,350, 400)
mat <- cbind(t1,t2, t3)

# First 10-day interval for `B`
t1 <- c(150,150)
# Second 10-day interval for `B`
t2 <- c(250,250)
mat2 <- cbind(t1,t2)

l1 <- list(mat, mat2)

int1 <- df %>%
  # arrange(ID) %>%   # skipped for readability of result
  mutate(new = floor_date(date, '10 day')) %>%
  mutate(new = if_else(day(new) == 31, new - days(10), new)) %>% 
  group_by(ID, new) %>%
  filter(Month == "3") %>% 
  group_split()

下面的代码尝试将lstMatl1 分开。我遇到的问题是lstMat 中的矩阵与l1 中的矩阵的维度不同。由于这种差异,当我尝试将一个与另一个分开时,我收到错误消息:Error in .x/.y : non-conformable arrays

g1 <- as.integer(gl(length(int1), 3, length(int1)))

f2 <- function(.int1, .int2) {
  t(outer(seq_along(.int1), seq_along(.int2), 
          FUN = Vectorize(function(i, j)  min(.int1[[i]]$jDate) - 
                            min(.int2[[j]]$jDate))))
}
lstMat <- map2(split(int1, g1), split(int1, g1), f2)
map2(l1, lstMat[1:2], `/`)

关于如何修改此代码以允许矩阵与列表的差异有什么想法吗?

问题: 我一直在尝试划分具有不同维度的矩阵。假设我运行一个自定义函数并以l1 结尾。 l1 中的矩阵对应于 int1 中的 10 天间隔,但我们没有得到 ID B 的第三个 10 天间隔的输出,因此是 2x2 矩阵。

规则: 在这种情况下,我想从lstMat[[2]] 中删除第三列,因为这是l1[[2]] 中缺少的那一列。情况并非总是如此,例如,如果 l1[[2]] 中缺少第二个 10 天间隔,那么我想删除 lsMat[[2]] 中的第二列。

我想根据最终从lstMat 中删除的特定间隔,通过使用int1 链接lstMatl1

我希望我没有让这更令人困惑。如果我这样做了,我深表歉意。

感谢您的宝贵时间。

【问题讨论】:

  • 在上面的示例中,使用每个列表的第二个元素,您希望将 2x2 矩阵除以 3x3 矩阵。你到底想让 R 为你做什么?也就是说,l1[[2]]/lstMat[[2]] 的预期输出是什么?
  • l1[[2]]/lstMat[[2]] 的预期输出是 2z2 矩阵。我想我希望删除其中一列以匹配l1[[2]] 的尺寸。本质上,我希望最终输出中矩阵的维度与l1 的维度相匹配。
  • 您可以这样做,但您会删除哪些列?如果l1[[j]] 是nxn 而lstMat[[j]] 是mxm,你是取lstMat[[j]] 的前n 行和列还是最后n 行和列或其他?为此,您必须有一个可以应用于所有情况的规则。
  • 我认为这取决于int1 中缺少的内容。在此示例中,int1 分为 3 个 10 天间隔。矩阵中的列/行对应于int1 中的单个区间。被删除的列取决于int1 中可能缺少的间隔。
  • 如果您能描述您将在问题中使用的规则,我们可能会帮助您弄清楚如何使其在 R 中发挥作用。

标签: r list matrix dplyr purrr


【解决方案1】:

这里的“g1”需要根据“lstMat”中每个元素的行数/维度进行动态调整。这可以通过rep 完成

library(purrr)
g1 <- rep(seq_along(lstMat), sapply(lstMat, nrow))
lstMat <- map2(split(int1, g1), split(int1, g1), f2)
map2(l1, lstMat[1:2], `/`)
[[1]]
      t1  t2  t3
[1,] Inf  20  15
[2,] -15 Inf  35
[3,] -10 -35 Inf

[[2]]
      t1  t2
[1,] Inf  25
[2,] -15 Inf

有些值是 Inf 只是因为我们在 'lstMat' 中有一些值是 '0'

lstMat[1:2]
$`1`
     [,1] [,2] [,3]
[1,]    0   10   20
[2,]  -10    0   10
[3,]  -20  -10    0

$`2`
     [,1] [,2]
[1,]    0   10
[2,]  -10    0

因此任何值除以 0 都会返回 Inf

【讨论】:

  • @JohnHuang lstMatlsMat 是不同的。你定义没有t
  • 抱歉打错了。我的意思是lstMat 我写了lsMat
  • @JohnHuang 你改过例子吗
  • @JohnHuang 这在我发布解决方案时有效,但现在我认为您可能已经更改了示例,因为未定义 lstMat。可能,g1 &lt;- rep(seq_along(l1), sapply(l1, nrow))int1 有点变化
  • @JohnHuang 正如我之前在 cmets 中提到的,int1 的长度为 6,与 l1 不一致。也许您只想选择直到它达到长度,即g1 &lt;- rep(seq_along(l1), sapply(l1, nrow)); lstMat &lt;- map2(split(int1[seq_len(length(g1))], g1), split(int1[seq_len(length(g1))], g1), f2); map2(l1, lstMat[1:2], /) [[1]] t1 t2 t3 [1,] Inf 20 15 [2,] -15 Inf 35 [3,] -10 -35 Inf [[2]] t1 t2 [1,] Inf 25 [2,] -15 Inf
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-12-06
  • 2014-04-22
  • 1970-01-01
  • 2013-10-20
  • 2011-05-31
  • 1970-01-01
  • 2019-08-05
相关资源
最近更新 更多