生成指定均值与递增标准差的人工DataFrame及代码错误排查
问题解决:生成指定标准差递增的DataFrame列表
需求说明
需要创建10个人工DataFrame组成的列表,每个DataFrame与原DataFrame的列名、行数一致,各列均值与原对应列相同,但标准差分别比原列增加10%、20%……直至100%(对应xs = seq(10, 100, 10))。
用户原代码及错误信息
原代码
#First define the function to draw random numbers given specific values of n, mean, sd rnorm2 <- function(n,mean,sd) {mean+sd*scale(rnorm(n))} #Create random df for replicability df = data.frame(replicate(9,sample(0:1,100,rep=TRUE))) names(df) = c("a", "b", "b" , "d", "e" , "f", "g" , "h" , "i") #Compute and store mean, standard deviation and size of each column in my dataset: # First, initialize vectors columns = c("a", "b", "b" , "d", "e" , "f", "g" , "h" , "i") ncols = length(df) column_means <- vector(mode = "numeric", length = ncols) column_sd <- vector(mode = "numeric", length = ncols) #Now loop through each column to obtain mean, standard deviation and increased standard deviation by x xs = seq(10, 100, 10) for(x in seq_along(xs)){ for (i in seq_along(columns)){ column_means[i] <- mean(df[[i]], na.rm = TRUE) column_sd[i] <- sd(df[[i]], na.rm = TRUE) column_sd_new[[i]][x] <- column_sd[i] + ((x/100)*column_sd[i]) } }
错误信息
Error in `*tmp*`[[i]] : subscript out of bounds
错误原因
- 未初始化对象导致下标越界:
column_sd_new没有提前声明和初始化,直接使用[[i]][x]赋值时,R无法找到该对象的索引,触发下标越界错误。 - 百分比计算逻辑错误:循环中
x是seq_along(xs)返回的索引值(1到10),而非xs中的百分比数值(10到100),计算新标准差时应该用xs[x]/100,否则实际只增加了1%到10%,不符合需求。 - 未生成目标DataFrame列表:原代码仅尝试计算新标准差,完全没有调用
rnorm2函数生成随机数据,也没有将数据组装成DataFrame并加入列表,未完成核心需求。
修正后的完整代码
# 定义生成指定均值、标准差的随机数函数(优化:移除scale的属性,返回纯数值) rnorm2 <- function(n, mean, sd) { mean + sd * scale(rnorm(n))[,1] # 取[,1]去掉scale返回的矩阵属性 } # 创建可复现的原DataFrame set.seed(123) # 设置随机种子保证结果可复现 df <- data.frame(replicate(9, sample(0:1, 100, rep=TRUE))) names(df) <- c("a", "b", "b", "d", "e", "f", "g", "h", "i") # 计算原数据的列均值和列标准差(只需计算一次,无需重复循环) column_means <- sapply(df, mean, na.rm = TRUE) column_sd <- sapply(df, sd, na.rm = TRUE) n_rows <- nrow(df) # 获取原数据行数 # 定义标准差递增的百分比序列 xs <- seq(10, 100, 10) # 初始化存储结果的列表 df_list <- vector("list", length(xs)) names(df_list) <- paste0("sd_increase_", xs, "%") # 循环生成每个DataFrame for (idx in seq_along(xs)) { # 计算当前百分比对应的新标准差:原标准差 * (1 + 百分比/100) new_sd <- column_sd * (1 + xs[idx]/100) # 为每列生成符合要求的随机数,组装成DataFrame new_df <- as.data.frame(lapply(seq_along(df), function(col_idx) { rnorm2(n_rows, column_means[col_idx], new_sd[col_idx]) })) # 设置列名与原DataFrame一致 names(new_df) <- names(df) # 将新DataFrame加入列表 df_list[[idx]] <- new_df } # 验证结果(可选) # 查看第一个列表元素的列均值和标准差 lapply(df_list[[1]], mean) lapply(df_list[[1]], sd)
代码说明
- 优化rnorm2函数:添加
[,1]提取scale返回矩阵的数值部分,避免后续DataFrame出现不必要的属性。 - 提前计算均值和标准差:原数据的均值和标准差只需计算一次,减少重复计算。
- 正确计算新标准差:使用
xs[idx]/100获取当前百分比,确保标准差按需求递增10%到100%。 - 生成并存储DataFrame列表:循环中调用
rnorm2生成每列的随机数据,组装成DataFrame后加入预先初始化的列表,完成核心需求。
内容的提问来源于stack exchange,提问作者txz10001
相关产品推荐
相关产品推荐

