在R中按月份分组对各列(食品项)进行有放回抽样
解决方案
核心思路
按月份分组提取每种食品的消费样本池,生成所有家庭×12个月的完整结构,再从对应月份的样本池中有放回抽样填充消费数据。
方法一:使用tidyverse工具链
library(tidyverse) # 生成原始数据(与用户提供的结构一致) data <- data.frame(matrix(NA, nrow=120, ncol=5)) names(data) <- c("ID", "Month", "Apple", "Maize", "Bread") data$ID <- 1:120 data$Month <- rep(1:12, each=10) # 注:若要让每户消费为独立随机值,将runif(12)改为runif(nrow(data)) data$Apple <- data$Month + 2 * runif(12) - 1 data$Maize <- data$Month + 2 * runif(12) - 1 data$Bread <- data$Month + 2 * runif(12) - 1 # 1. 按月份整理每种食品的样本列表 monthly_samples <- data %>% group_by(Month) %>% summarise( Apple_samples = list(Apple), Maize_samples = list(Maize), Bread_samples = list(Bread), .groups = "drop" ) # 2. 构建全量ID×Month的目标结构 data2 <- expand_grid(ID = 1:120, Month = 1:12) # 3. 关联样本池并抽样填充消费数据 data2 <- data2 %>% left_join(monthly_samples, by = "Month") %>% mutate( Apple = map_dbl(Apple_samples, ~sample(.x, size = 1, replace = TRUE)), Maize = map_dbl(Maize_samples, ~sample(.x, size = 1, replace = TRUE)), Bread = map_dbl(Bread_samples, ~sample(.x, size = 1, replace = TRUE)) ) %>% select(ID, Month, Apple, Maize, Bread)
方法二:使用Base R
# 生成原始数据 data <- data.frame(matrix(NA, nrow=120, ncol=5)) names(data) <- c("ID", "Month", "Apple", "Maize", "Bread") data$ID <- 1:120 data$Month <- rep(1:12, each=10) data$Apple <- data$Month + 2 * runif(12) - 1 data$Maize <- data$Month + 2 * runif(12) - 1 data$Bread <- data$Month + 2 * runif(12) - 1 # 按月份拆分每种食品的样本集合 apple_by_month <- split(data$Apple, data$Month) maize_by_month <- split(data$Maize, data$Month) bread_by_month <- split(data$Bread, data$Month) # 构建全量ID×Month的目标结构 data2 <- expand.grid(ID = 1:120, Month = 1:12) # 对每个月份的食品数据有放回抽样填充 data2$Apple <- sapply(data2$Month, function(m) { sample(apple_by_month[[as.character(m)]], size = 1, replace = TRUE) }) data2$Maize <- sapply(data2$Month, function(m) { sample(maize_by_month[[as.character(m)]], size = 1, replace = TRUE) }) data2$Bread <- sapply(data2$Month, function(m) { sample(bread_by_month[[as.character(m)]], size = 1, replace = TRUE) }) # 调整列顺序与目标结构一致 data2 <- data2[, c("ID", "Month", "Apple", "Maize", "Bread")]
关键说明
sample(..., replace = TRUE)实现有放回抽样,保证每次抽样可重复选取原数据中的值。- 原数据中每个月的同食品消费值是重复的(因
runif(12)仅生成12个值),若需要每户消费为独立随机值,将runif(12)替换为runif(nrow(data))即可。
内容的提问来源于stack exchange,提问作者heikeehee
相关产品推荐
相关产品推荐

