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

使用R语言purrr::map实现两个data.frame行级遍历计算

问题描述

我有两个存储公式计算用值的data.frame,需要将df1的每一行和df2的每一行组合进行计算。已经用嵌套for循环实现了预期结果,但尝试用purrr::map实现时出现报错:

map2(df1,df2,function(.x,.y) {(eval(str2lang(.x$h))*eval(str2lang(.y$limit))*eval(str2lang(.x$ED)))/eval(str2lang(.y$zone))})
#Error in `map2()`:
#! Can't recycle `.x` (size 4) to match `.y` (size 3).
#Run `rlang::last_error()` to see where the error occurred.

尝试嵌套map调用也无法正确获取列值,求如何用purrr::map实现该需求?

原始数据与for循环代码

library(tibble)

df1 <- tibble(Type=c("atype","btype","ctype"),
              h=c("1","2","3"),
              w=c("4","5","6"),
              ED=c("101","102","103"))

df2 <- tibble(Item=c("123-htc","but-456","xtc","newID"),
              limit=c("rnorm(1)","12","13","14"),
              zone=c("30","40","30","11"))
# 注:数据框中的值存为字符串,这样可以支持调用随机数函数

resItm <- list()
resTyp <- list()


for (i in 1:length(df1$Type)) {
   h <- NULL
   w <- NULL
   ED <- NULL
   limit <- NULL
   zone <- NULL
   for (j in 1:length(df2$Item)) {
      Typ<-df1[i,]
      Itm<-df2[j,]
      h<-eval(str2lang(Typ$h))
      w<-eval(str2lang(Typ$w))
      ED<-eval(str2lang(Typ$ED))
      limit<-eval(str2lang(Itm$limit))
      zone<-eval(str2lang(Itm$zone))
      
      res1 <- (h * limit * ED) / (zone)
      
      resItm[[j]] <- list(Item=Itm$Item, Result=res1)
   }
   resTyp[[i]] <- list(Type=Typ$Type, Res_Item = resItm)
}

str(resTyp)

解决方案

问题根源

你用map2报错是因为它默认按列同时遍历两个data.frame,但你需要的是df1每行和df2每行的全组合计算,所以得用嵌套map来实现行对行的遍历。

实现代码

library(purrr)
library(tibble)

# 先把两个数据框拆成按行的列表,方便逐行遍历
df1_rows <- split(df1, seq(nrow(df1)))
df2_rows <- split(df2, seq(nrow(df2)))

# 嵌套map实现全组合计算
resTyp_map <- map(df1_rows, function(row1) {
  # 内层遍历所有df2行,计算当前df1行和每个df2行的结果
  resItm <- map(df2_rows, function(row2) {
    h <- eval(str2lang(row1$h))
    ED <- eval(str2lang(row1$ED))
    limit <- eval(str2lang(row2$limit))
    zone <- eval(str2lang(row2$zone))
    
    result <- (h * limit * ED) / zone
    list(Item = row2$Item, Result = result)
  })
  
  # 整理当前df1行的结果结构
  list(Type = row1$Type, Res_Item = resItm)
})

# 查看结果结构,和原for循环输出完全一致
str(resTyp_map)

简化写法

如果想让代码更简洁,可以用purrr的匿名函数语法:

resTyp_map <- map(df1_rows, ~{
  resItm <- map(df2_rows, ~{
    result <- (eval(str2lang(.x$h)) * eval(str2lang(.y$limit)) * eval(str2lang(.x$ED))) / eval(str2lang(.y$zone))
    list(Item = .y$Item, Result = result)
  }, .y = .x)
  list(Type = .x$Type, Res_Item = resItm)
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:46:29