合并两个大小和名称不同的数据框

时间:2020-08-30 15:34:15

标签: r dataframe

你好,我有一个关于数据帧的问题。可以说我有一个数据框diamonds_2[5000,5],其中我的列是carat, color, clarity, price, cut。我创建了一个名为results的新数据框,在其中我使用以下命令计算每种颜色组合和切割的平均价格:

results<tapply(diamonds_2$price,list(diamonds_2$color,diamonds_2$cut),mean)
results <- data.frame(results)

现在,我正在尝试通过将原始数据框diamonds_2与结果数据框组合来创建数据框,以便对于每颗钻石,您都可以看到价格,并且在价格旁边还可以看到平均价格(基于组合颜色和切割)。我认为我必须使用merge命令,但是我很困惑,因为我不知道如何使用by.x或by.y命令。因为我的结果数据框在一个轴(行)上具有颜色(D,E,F,G,J,I,K),而在另一轴(列上)上具有剪切变量(高于平均值,低于平均值,很好)

2 个答案:

答案 0 :(得分:0)

让我们以一种稍有不同的方式来执行此操作。您需要inner_join中的dplyrdplyr包也可以完成您的第一部分工作。看来您的diamonds_2数据是内置diamonds数据集的子集。

library(dplyr)
# building data with columns like yours
diamonds_2 <- diamonds %>% select(carat, color, clarity, price, cut)
# I'll do the summary stats within the join to avoid having to make a new object in memory
diamonds_2 %>%
  left_join(diamonds_2 %>%
              group_by(color, cut) %>%
              summarize(mean_price = mean(price)))
`summarise()` regrouping output by 'color' (override with `.groups` argument)
Joining, by = c("color", "cut")
# A tibble: 53,940 x 6
   carat color clarity price cut       mean_price
   <dbl> <ord> <ord>   <int> <ord>          <dbl>
 1 0.23  E     SI2       326 Ideal          2598.
 2 0.21  E     SI1       326 Premium        3539.
 3 0.23  E     VS1       327 Good           3424.
 4 0.290 I     VS2       334 Premium        5946.
 5 0.31  J     SI2       335 Good           4574.
 6 0.24  J     VVS2      336 Very Good      5104.
 7 0.24  I     VVS1      336 Very Good      5256.
 8 0.26  H     SI1       337 Very Good      4535.
 9 0.22  E     VS2       337 Fair           3682.
10 0.23  H     VS1       338 Very Good      4535.
# ... with 53,930 more rows

答案 1 :(得分:0)

考虑使用tapply而不是ave进行内联聚合,而不会折叠行以分配新列。

diamonds_2$avg_price <- with(diamonds_2, ave(price, color, cut, FUN=mean))

由于您可能精通Python,因此类似于groupby.transform

diamonds_2['avg_price'] = diamonds_2.groupby(['color', 'cut'])['price'].transform('mean')

甚至是SQL的窗口函数(请检查R的sqldf或Python的pandasql

SELECT color
       , cut
       , AVG(price) OVER(PARTITION BY color, cut) AS avg_price
FROM diamonds_2