首页 > 解决方案 > 如何在 dplyr 包中使用权重

问题描述

我不明白加权在dplyr::sample_n函数中是如何工作的。我有一个非常小的数字列表(范围从 0.1020457 到 0.1789028),我需要对采样进行加权,以便在下端、上端和中间得到一些。但由于数字如此相似,我不知道该怎么做。我也不想将我的采样限制在某个范围内(例如数字> 0.16),我只希望那些更有可能被采样的。

我可以使范围更大(-1.552115 到 2.008253),但这意味着按数据缩放,我不能用负数加权。我必须做类似 abs(数字 - 最大值)之类的事情。这是我正在做的一个例子:

sample_n(data.frame(scaledMeasurement$V1), 4, 
         replace = FALSE, 
         weight = abs((scaledMeasurement $V1) - max(scaledMeasurement $V1)))

这是我的数据的一部分:

Measurement ID    
0.8022473 1
1.6991193 2
0.7262765 3
0.3903775 4
-1.5521155 5
-0.7821887 6

标签: rdplyr

解决方案


如果您的目标是获得一个样本,其中包含一些在低端,一些在中值附近,一些在末端,那么避免权重并只使用group_by+会容易得多sample_n

library(tidyverse)
df = tibble(my_nums = runif(10,0.1020457,0.1789028))    
df %>% 
  mutate(quantile = case_when(
    my_nums <= quantile(my_nums, probs = c(0.33)) ~ "a",
    my_nums <= quantile(my_nums, probs = c(0.67)) ~ "b",
    TRUE ~ "c"
  )) %>% 
  group_by(quantile) %>% 
  sample_n(2)

生产:

    my_nums quantile
    <dbl> <chr>   
1   0.105 a       
2   0.105 a       
3   0.151 b       
4   0.124 b       
5   0.173 c       
6   0.172 c 

但是,如果您想使用权重,则sample_n要求权重与被采样的向量的长度相同,并且权重的总和等于 1。您可以根据组的细分添加权重列 (正如我在上面显示的分位数),按此分组,生成一个介于 1 和长度之间的随机数,取消分组,然后将该列中的值除以其总和。像这样:

df %>% 
  mutate(quantile = case_when(
    my_nums <= quantile(my_nums, probs = c(0.33)) ~ "a",
    my_nums <= quantile(my_nums, probs = c(0.67)) ~ "b",
    TRUE ~ "c"
  )) %>% 
  group_by(quantile) %>% 
  mutate(weight = sample(seq(1,length(my_nums)),length(my_nums))) %>% 
  ungroup %>%  arrange(quantile) %>% 
  mutate(weight = weight / sum(weight)) %>% 
  sample_n(6, weight = weight)

推荐阅读