如何在R中执行颜色的加权平均?

xkrw2x1b  于 2023-04-03  发布在  其他
关注(0)|答案(2)|浏览(136)

我将以下数据集(dat.an)作为.csv文件:

Animal,Bias,Colour
Frog,2,"#0000FF"
Frog,1,"#FFFFFF"
Dog,16,"#FFFFFF"
Cat,2,"#FF0000"
Frog,3,"#FF0000"
Cat,8,"#0000FF"
Dog,12,"#0000FF"
Cat,8,"#FFFFFF"
Cat,12,"#0000FF"
Dog,2,"#0000FF"

我想根据Animal进行分组,并生成一个加权平均值Colour,其中权重在bias列中。
我已经做到了:

library(tidyverse)

dat.an %>%
  group_by(Animal)

没有as.colour选项来处理十六进制颜色。所以我不知道如何进行。

oxalkeyp

oxalkeyp1#

您可以执行以下操作:

df <- data.frame(Animal = c('Frog', 'Frog', 'Dog', 
                            'Cat', 'Frog', 'Cat', 'Dog',
                            'Cat', 'Cat', 'Dog'),
                 Bias = c(2, 1, 16, 2, 3, 8, 12, 8, 12, 2),
                 Colour = c('#0000FF', '#FFFFFF', 
                            '#FFFFFF', '#FF0000', '#FF0000', 
                            '#0000FF', '#0000FF', '#FFFFFF', 
                            '#0000FF', '#0000FF'))
library(tidyverse)
new_df <- df |>
  transmute(
            Animal = Animal,
            red = strtoi(substr(Colour,2,3),16),
            green = strtoi(substr(Colour,4,5),16),
            blue = strtoi(substr(Colour,6,7),16),
            weight = Bias
            ) |>
  group_by(Animal) |>
  summarise(
            red = sum(red * weight),
            green = sum(green * weight),
            blue = sum(blue * weight),
            weight = sum(weight)
            ) |>
  select(Animal, everything()) |>
  transmute(
            Animal = Animal,
            red = red/weight,
            green = green/weight,
            blue = blue/weight
            ) |>
  transmute(
            Animal = Animal,
            Color = rgb(red,green,blue, maxColorValue = 255)
            )

在第一个transmute()中,十六进制代码分隔为0255Biasweight之间的rgb值。
然后将weight乘以rgb并将rgb和weight按Animal分组并将Animal列带回(select(Animal, everything())),然后将每行的RGB除以weight,最后将RGB转换为十六进制。
还有一些其他的方法可以做到这一点,但我认为这是学习R的好方法。new_df是这样的:

> new_df
# A tibble: 3 × 2
  Animal Color  
  <chr>  <chr>  
1 Cat    #5544EE
2 Dog    #8888FF
3 Frog   #AA2A7F
>
91zkwejq

91zkwejq2#

使用data.table

library(data.table)
setDT(dat.an)

cols <- c("red", "green", "blue")
dat.an[, (cols) := as.list(col2rgb(Colour)), Colour][
  , lapply(.SD, weighted.mean, w = Bias), Animal, .SDcols = cols][
  , .(Colour = rgb(red, green, blue, maxColorValue = 255)), Animal]

结果

#    Animal  Colour
# 1:   Frog #AA2A7F
# 2:    Dog #8888FF
# 3:    Cat #5544EE

相关问题