在R语言中按比例随机对数据框列值保留不同小数位数
非均匀随机保留小数位的解决方案
问题背景
给定数据集:
df <- data.frame(id=1:10, v1=c(2.35456185,1.44501001,2.98712312,0.12345123,0.96781234, 1.23934551,5.00212233,4.34120000,1.23443213,0.00112233), v2=c(0.22222222,0.00123456,2.19024869,0.00012000,0.00029848, 0.12348888,0.46236577,0.85757000,0.05479729,0.00001202))
需要随机为v1和v2列的观测值保留小数位:10%保留1位,40%保留2位,50%保留3位。
解决方案
核心逻辑是先为每一行随机分配目标小数位数,再按该位数对列值取整。
1. 生成随机小数位数向量
用sample()按指定比例生成每个观测对应的保留位数,设置随机种子可让结果复现:
set.seed(123) # 可选,保证结果一致 decimal_digits <- sample(c(1,2,3), nrow(df), replace = TRUE, prob = c(0.1, 0.4, 0.5))
2. 自定义取整函数
用mapply()实现逐元素匹配位数取整:
round_by_digit <- function(x, digits) { mapply(round, x, digits) }
3. 应用函数处理数据
对v1和v2列分别应用取整逻辑:
df$v1 <- round_by_digit(df$v1, decimal_digits) df$v2 <- round_by_digit(df$v2, decimal_digits)
用tidyverse简化操作(可选)
如果习惯dplyr语法,可一站式完成:
library(dplyr) set.seed(123) df <- df %>% mutate( decimal_digits = sample(c(1,2,3), n(), replace = TRUE, prob = c(0.1,0.4,0.5)), v1 = mapply(round, v1, decimal_digits), v2 = mapply(round, v2, decimal_digits) ) %>% select(-decimal_digits) # 移除临时生成的位数列
示例输出
运行后得到的结果(因随机性会有差异):
id v1 v2 1 1 2.40 0.22 2 2 1.45 0.00 3 3 2.99 2.19 4 4 0.123 0.000 5 5 0.97 0.00 6 6 1.239 0.123 7 7 5.00 0.46 8 8 4.341 0.858 9 9 1.23 0.05 10 10 0.001 0.000
内容的提问来源于stack exchange,提问作者iGada
相关产品推荐
相关产品推荐

