如何合并diamonds_2与按color、cut分组的results数据框?
解决DataFrame合并问题:匹配color和cut组合的平均价格
嘿,我来帮你搞定这个合并的难题!你现在的问题核心是当前的results结构不适合直接和原始数据合并——因为tapply生成的结果是宽格式(行是color,列是cut),而merge需要两边有对应的匹配列(color和cut都得是单独的列)。下面分步骤给你解决:
第一步:把results转换成适合合并的长格式
首先得把宽格式的results转成长格式,也就是让color、cut、avg_price各占一列。这里提供两种方法,选你顺手的就行:
方法1:用Base R处理
# 先把行名(color值)变成单独的color列 results$color <- rownames(results) # 把宽格式转成长格式 results_long <- reshape(results, direction = "long", varying = names(results)[-ncol(results)], # 指定要转换的列(除了color) v.names = "avg_price", # 平均价格列的名字 timevar = "cut", # 用来区分不同cut的列名 times = names(results)[-ncol(results)]) # cut的具体取值 # 去掉自动生成的行名,让数据更整洁 rownames(results_long) <- NULL
方法2:用tidyverse(更简洁)
如果你习惯用tidyverse工具包,代码会更直观:
library(tidyr) library(dplyr) results_long <- results %>% rownames_to_column(var = "color") %>% # 行名转成color列 pivot_longer(cols = -color, # 除了color列,其他列都转成cut的取值 names_to = "cut", values_to = "avg_price")
转换后的results_long会是这样的结构:
| color | cut | avg_price |
|---|---|---|
| D | above average | xxx |
| D | below average | xxx |
| ... | ... | ... |
第二步:合并原始数据和平均价格
现在results_long和diamonds_2都有color和cut这两个匹配列了,直接用merge或者left_join就能搞定:
用Base R的merge函数
diamonds_combined <- merge(diamonds_2, results_long, by = c("color", "cut"))
这里by = c("color", "cut")表示同时用这两列作为匹配条件,确保每行原始数据都能找到对应的color+cut组合的平均价格。
用dplyr的left_join(推荐,保留原始数据所有行)
如果你想确保原始数据的5000行都被保留(哪怕某个color+cut组合没有平均价,也会显示NA),用left_join更稳妥:
diamonds_combined <- diamonds_2 %>% left_join(results_long, by = c("color", "cut"))
额外小技巧:一步生成可合并的平均价格表
其实你一开始计算平均价格的时候,就可以直接生成适合合并的长格式结果,省去转换步骤:
library(dplyr) results_long <- diamonds_2 %>% group_by(color, cut) %>% # 按color和cut分组 summarize(avg_price = mean(price), .groups = "drop") # 计算每组平均价格
这样得到的results_long直接就能和原始数据合并,效率更高~
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

