如何在R中对列表元素的所有组合应用自定义函数以计算产品各评分维度的平均值
嘿,我来帮你搞定这个计算产品评分平均值的问题!你的需求很明确:给每个产品的三个评分维度分别算平均值,最终生成目标格式的结果。咱们一步步来解决:
首先,先把你的示例数据集整理成R可用的格式
先把你给出的调研数据转成R的数据框,方便后续操作:
# 构造示例数据集 dat <- data.frame( Cust_id = c(1,2,3,1,4,4,5), product = c("A","B","A","C","A","B","D"), rating1 = c(2,3,9,4,2,4,9), rating2 = c(3,7,5,5,3,5,4), rating3 = c(7,2,8,7,5,6,1) )
方法一:用data.table直接分组聚合(最简洁高效)
其实你不用复杂的自定义函数,data.table的分组功能就能直接搞定,这也是最推荐的方式:
library(data.table) setDT(dat) # 按product分组,计算每个评分列的平均值 result <- dat[, .( avg_rating1 = mean(rating1, na.rm = TRUE), avg_rating2 = mean(rating2, na.rm = TRUE), avg_rating3 = mean(rating3, na.rm = TRUE) ), by = product] # 查看最终结果 print(result)
运行后会得到真实的平均值结果(注:你给出的期望输出可能是示例笔误,比如A的rating1实际平均值是(2+9+2)/3≈4.33,代码会计算准确值):
product avg_rating1 avg_rating2 avg_rating3 1: A 4.333333 3.666667 6.666667 2: B 3.500000 6.000000 4.000000 3: C 4.000000 5.000000 7.000000 4: D 9.000000 4.000000 1.000000
方法二:修正你的自定义函数,遍历所有产品-评分组合
如果你坚持想用自定义函数的思路,咱们可以先修正函数逻辑,再遍历所有组合:
第一步:修正自定义函数
原来的函数没有正确筛选数据,也不支持单个组合的计算,咱们改成接收单个产品名和评分列名的版本:
avg.rate <- function(product_name, rating_col, dat) { require(data.table) setDT(dat) # 筛选对应产品的数据,计算指定评分列的平均值 dat[product == product_name, mean(get(rating_col), na.rm = TRUE)] }
第二步:生成所有产品和评分的组合
用expand.grid生成所有需要计算的产品-评分对:
# 生成所有产品与评分维度的组合 combinations <- expand.grid( Product = c('A',"B","C","D"), rating = c('rating1','rating2','rating3'), stringsAsFactors = FALSE )
第三步:遍历组合计算平均值,并转换为目标格式
用apply遍历每个组合,然后把长格式的结果转成宽格式:
# 计算每个组合的平均值 combinations$avg_value <- apply(combinations, 1, function(x) { avg.rate(x["Product"], x["rating"], dat) }) # 转换为你需要的宽格式 result_wide <- reshape(combinations, idvar = "Product", timevar = "rating", direction = "wide") # 重命名列名匹配期望格式 colnames(result_wide) <- c("product", "avg_rating1", "avg_rating2", "avg_rating3") # 查看结果 print(result_wide)
这个方法会得到和方法一完全一致的结果。
小提醒
你之前的自定义函数有两个小问题:
dat$Product %in% input$Product只是做了逻辑判断,没有实际筛选数据;- 参数设计没有针对单个产品-评分组合,导致无法直接遍历所有情况。修正后就可以正常工作啦!
内容的提问来源于stack exchange,提问作者mydt
相关产品推荐
相关产品推荐

