使用 dplyr 从分组 data.frame 中以组级汇总统计数据为条件进行行采样

2024-02-03

In 这篇文章关于对采样行数下限的比例进行采样 https://stackoverflow.com/questions/74176819/sample-a-percentage-of-entries-in-a-dataframe-but-with-a-lower-limit/74178225#74178225我编写了一个函数(见下文),它采用包含一些组标识符的 data.frame,将 data.frame 按组拆分为列表,然后对比例和最小行数中的较大者进行采样。

虽然这有效,但我想知道是否有一种有效的方法可以做到这一点summarise或者以其他方式不分割输出group_by()进入列表,然后迭代列表的元素map/lapply类函数。这个想法是将数据传递给group_by()然后到summarise(),我将计算每组中的行数,然后使用相应的比例或最小数量进行采样if_else方法。然而我发现这产生了各种范围问题或类型冲突。例如,cur_group or cur_data在同一个汇总调用中进行计数和子集似乎很有用,但我不确定如何正确使用它们。

任何人都知道如何在summarise()或以其他方式避免split()ing 之外的数据summarise()?

library(dplyr)

# Example data: 10 rows in group a, 100 in group b
df <- data.frame(x = 1:110,
                 y = rnorm(110),
                 group = c(rep("a", 10), rep("b", 100)))

# Proportion and minimum number of rows to sample
sample_prop <- 0.5
sample_min <- 8

# Group the data and split each group into a list of tibbles
df_list <- df %>% group_by(group) %>% group_split()

# Checks if the number of rows that would be sampled is below the minimum. If so, 
# sample the minimum number of rows, otherwise sample the proportion. This is 
# what I'm trying to do within a summarise call.
conditional_sample <- function(dat, sample_min, sample_prop) {
  if (nrow(dat) * sample_prop < sample_min) {
    slice_sample(dat, n = sample_min)
  } else{
    slice_sample(dat, prop = sample_prop)
  }
}

# Apply the function to our list -- ideally this would be unecessary
# within summarise
sampled <- df_list %>%
  lapply(., function(x) {
    conditional_sample(x, sample_min, sample_prop)
  })

bind_rows(sampled) # check out data

一个简单的方法是使用max() of sample_min and sample_prop * n()作为样本大小:

With slice():

library(dplyr)

sample_prop <- 0.5
sample_min <- 8


df %>%
  group_by(group) %>%
  slice(sample(n(), max(sample_min, floor(sample_prop * n())))) %>%
  ungroup()

# A tibble: 58 × 3
       x      y group
   <int>  <dbl> <chr>
 1     1  1.01  a    
 2     3 -0.389 a    
 3     4  0.559 a    
 4     5 -0.594 a    
 5     7 -0.415 a    
 6     8 -1.63  a    
 7     9 -2.27  a    
 8    10 -0.422 a    
 9    11  0.673 b    
10    12 -1.23  b    
# … with 48 more rows
# ℹ Use `print(n = ...)` to see more rows

或者等效于filter():

df %>%
  group_by(group) %>%
  filter(row_number() %in% sample(n(), max(sample_min, floor(sample_prop * n())))) %>%
  ungroup()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 dplyr 从分组 data.frame 中以组级汇总统计数据为条件进行行采样 的相关文章

随机推荐