You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

矩阵乘法后展开Tibble遇问题:unnest未达预期结果

问题描述

想要计算两个向量的矩阵乘积,示例代码如下:

a <- tibble(n=c("A", "B"), y=c(10,20))
b <- tibble(x=c(5, 15))

res <- a %>% 
  mutate(rotated = map2(y, b, ~ .x %*% .y)) %>% 
  unnest(rotated)

执行后看似正常,但预期unnest后得到2×4的tibble,实际却是2×3的结构:

n         y rotated[,1]  [,2]
  <chr> <dbl>       <dbl> <dbl>
1 A        10          50   150
2 B        20         100   300

查看res$rotated时还会报错:

Error in if (nchar(current) > nchars) { : 
  missing value where TRUE/FALSE needed 

尝试使用bind_cols的方案也无法解决问题。

解决方案

问题根源

  1. map2(y, b, ~ .x %*% .y)中,b是完整tibble而非向量,map2会将整个tibble作为单个元素传入.y,导致每次计算得到1×2的矩阵,而非预期的拆分后的值;
  2. unnest处理矩阵列时,会直接将矩阵的列展开为数据框列,同时原rotated列会被移除,这就是访问res$rotated报错的原因——该列已不存在。

修正代码

方案1:提取向量+转换矩阵为tibble

先提取b中的向量,计算后将矩阵转为tibble,确保unnest能正确展开为单独列:

library(tidyverse)

a <- tibble(n=c("A", "B"), y=c(10,20))
b <- tibble(x=c(5, 15))

# 提取b的x向量
b_vec <- pull(b, x)

res <- a %>% 
  mutate(rotated = map(y, ~ as_tibble(t(.x %*% b_vec)))) %>% 
  unnest(rotated)

# 可选:重命名列使其更直观
res <- res %>% rename(rot1 = V1, rot2 = V2)

执行后得到预期的2×4结构:

n         y  rot1  rot2
  <chr> <dbl> <dbl> <dbl>
1 A        10    50   150
2 B        20   100   300

方案2:直接向量化计算(更高效)

如果仅需标量与向量的矩阵乘法,可跳过map直接用向量化操作:

res <- a %>%
  mutate(
    rot1 = y * b_vec[1],
    rot2 = y * b_vec[2]
  )

结果与方案1完全一致,且代码更简洁高效。

关于访问res$rotated报错的说明

unnest(rotated)执行后,原rotated列已被拆解为对应矩阵列(方案1中是V1、V2),res中不再存在名为rotated的列,因此访问res$rotated会触发错误。可通过colnames(res)查看当前所有列名确认。

内容的提问来源于stack exchange,提问作者MPB_2022

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 23:04:53