如何在R中通过mutate和map为嵌套数据框生成runif分布
问题与解法
问题描述
现有如下结构的tibble数据:
# A tibble: 3 × 4 Species min max sd <fct> <dbl> <dbl> <dbl> 1 setosa 4.3 5.8 0.352 2 versicolor 4.9 7 0.516 3 virginica 4.9 7.9 0.636
需要为每个分组生成100个介于对应行min和max之间的随机样本,新增一列存储这些随机数序列。尝试了以下代码但未成功:
mutate( out = map(runif(min = min, max = max, n = 100)) )
以及完整嵌套版代码:
iris %>% group_by(Species) %>% summarise( min = min(Sepal.Length), max = max(Sepal.Length), sd = sd(Sepal.Length) ) %>% ungroup() %>% group_by(Species) %>% nest() %>% mutate( out = map(data, ~ runif(min = min, max = max, n = 100)) )
问题分析
- 第一种写法错误:
map需要遍历输入对象,但直接传入runif的调用结果不符合map的使用逻辑,且runif无法直接按行处理列向量生成多组100个随机数。 - 嵌套版写法错误:
map内部的min和max未正确指向嵌套数据框中的对应列,无法提取每个分组的区间值。
正确解法
解法1:使用map2直接处理列
由于需要同时遍历min和max两列,purrr::map2是更合适的选择,它可以并行处理两个输入向量:
library(tidyverse) # 生成基础统计数据 iris_stats <- iris %>% group_by(Species) %>% summarise( min = min(Sepal.Length), max = max(Sepal.Length), sd = sd(Sepal.Length) ) %>% ungroup() # 新增随机数序列列 iris_stats %>% mutate( out = map2(min, max, ~ runif(n = 100, min = .x, max = .y)) )
执行后,out列会成为列表列,每个元素对应一个分组的100个随机数序列。
解法2:修正嵌套数据框代码
如果坚持使用嵌套数据框,需在map内部通过.x(嵌套的子数据框)提取min和max:
iris %>% group_by(Species) %>% summarise( min = min(Sepal.Length), max = max(Sepal.Length), sd = sd(Sepal.Length) ) %>% ungroup() %>% group_by(Species) %>% nest() %>% mutate( out = map(data, ~ runif(n = 100, min = .x$min, max = .x$max)) ) %>% # 可选:移除嵌套的data列,恢复原数据结构 unnest(data)
这里.x代表每个Species对应的嵌套子数据框,通过.x$min和.x$max即可获取该分组的区间值,生成符合要求的随机数序列。
内容的提问来源于stack exchange,提问作者user113156
相关产品推荐
相关产品推荐

