我想创建随机模拟数据,如下所示。
__ID__|__Amount__
1 20
1 14
1 9
1 3
2 11
2 5
2 2从随机数开始,但是具有相同ID的第二个数字应该小于第一个数字,并且第三个数字必须小于第二个数字。开始的最大数量应该是20。
发布于 2018-02-20 13:55:46
您可以使用tidyverse首先创建数据,然后根据需要对其进行排序:
set.seed(0)
df <- data.frame(id = rep(1:3,10), amt = sample(1:20, 30, replace = TRUE))
df %>%
group_by(id) %>%
arrange(id, desc(amt))发布于 2018-02-20 12:49:22
这是一个棘手的问题,如果您希望Amount列是真正的随机值,您可以使用递归调用来递归地使用sample:
## Recursively sampling from a uniform distribution
recursive.sample <- function(start, end, length, results = NA, counter =0) {
## To enter the recursion, counter must be smaller than the length out
## and the last result must be smaller than the starting point (except the firs time)
if(counter < length && ifelse(counter != 0, results[counter] > start, TRUE)){
## Increment the counter
counter <- counter + 1
## Sample between start and the last result or the start and the end of the vector
results[counter] <- ifelse(counter != 1, sample(start:results[counter-1], 1), sample(start:end, 1))
## Recursive call
return(recursive.sample(start = start, end = end, length = length, results = results, counter = counter))
} else {
## Exit the recursion
return(results)
}
}
## Example
set.seed(0)
recursive.sample(start = 1, end = 20, length = 3, results = NA, counter = 0)
#[1] 18 5 2或者(以更简单的方式),您可以使用sort(sample())
set.seed(0)
sort(sample(1:20, 3), decreasing = TRUE)
#[1] 18 7 6请注意,由于在递归函数中采样较高值的概率较低,因此结果不同。
然后,您可以使用您选择的函数轻松创建表,如下所示:
set.seed(123)
## The ID column
ID <- c(rep(1, 4), rep(2,3))
## The Amount column
Amount <- c(recursive.sample(1, 20, 4, NA, 0), recursive.sample(1, 11, 3, NA, 0))
## The table
cbind(ID, Amount)
# ID Amount
#[1,] 1 18
#[2,] 1 5
#[3,] 1 2
#[4,] 1 2
#[5,] 2 10
#[6,] 2 3
#[7,] 2 3或者,再次使用简单的sort(sample())函数,以获得更高的选择较大数字的概率。
发布于 2018-02-20 21:37:49
两种方法,一种使用dplyr,另一种仅使用基本R函数。这些与前面的两个解决方案略有不同。
我使用了排序ID列,但这不是必需的。
方法1
rm(list = ls())
set.seed(1)
df <- data.frame(ID = rep(1:3, each = 5))
df %>% group_by(ID) %>%
mutate(Amount = sort(sample(1 : 20, n(), replace = T), decreasing = TRUE))方法2
rm(list = ls())
set.seed(1)
df <- data.frame(ID = rep(1:3, each = 5))
df$Amount <- NA
uniq_ID <- unique(df$ID)
index_lst <- lapply(uniq_ID, function(x) which(df$ID == x))
res <- lapply(index_lst, function(x) sort(sample(1 : 20, length(x)),
decreasing = TRUE))
df$Amount[unlist(index_lst)] <- unlist(res)方法2.5
这比第二种方法更复杂。
rm(list = ls())
set.seed(1)
df <- data.frame(ID = rep(1:3, each = 5))
df$Amount <- NA
tab <- as.data.frame(table(df$ID))
lapply(1 : nrow(tab), function(x) df$Amount[which(df$ID == tab$Var1[x])] <<-
sort(sample(1 : 20, tab$Freq[x]), decreasing = TRUE))https://stackoverflow.com/questions/48877375
复制相似问题