我有以下玩具数据集
bill = Bill()
bill.billId = 14
bill.bill.name = 'bills/output.csv'
bill.save()
其中每个ID是个体受访者,回答3个问题(在实际数据集中,回答的问题数量是可变的,因此我不能依赖每个ID的特定行数)。
我想创建一个新的(更大的)数据集,根据set.seed(100)
df <- data.frame(ID = rep(1:5, each = 3),
value = sample(LETTERS, 15, replace = TRUE),
weight = rep(c(0.1, 0.1, 0.5, 0.2, 0.1), each = 3))
df
ID value weight
1 1 I 0.1
2 1 G 0.1
3 1 O 0.1
4 2 B 0.1
5 2 M 0.1
6 2 M 0.1
7 3 V 0.5
8 3 J 0.5
9 3 O 0.5
10 4 E 0.2
11 4 Q 0.2
12 4 W 0.2
13 5 H 0.1
14 5 K 0.1
15 5 T 0.1
中的权重从各个ID中抽样。
weight
从ID的概率抽样转移到新probs <- data.frame(ID = unique(df$ID))
probs$prob <- NA
for(i in 1:nrow(probs)){
probs$prob[i] <- df[df$ID %in% probs$ID[i],]$weight[1]
}
probs$prob <- probs$prob / sum(probs$prob)
sampledIDs <- sample(probs$ID, size = 10000, replace = TRUE, prob = probs$prob)
head(sampledIDs,10)
[1] 4 3 3 3 4 4 2 4 2 3
的实际创建,这让我很难过。我试过了
data.frame
但显然没有考虑ID重复的事实。我也试过一个循环:
dfW <- df[df$ID %in% sampledIDs,]
但是,如果使用大型数据集,痛苦地会慢下来。
非常感谢任何帮助。
(另外,如果有更简单的方法来进行ID的概率选择,那么听起来也很棒!)
答案 0 :(得分:1)
代码速度很低,因为您在for
循环的每个循环中调整数据框的大小。这是我的建议。创建一个数据框,其最终大小为数据框dfW
在for
循环之前的大小。然后将df
循环中数据框dfW
的值分配给for
。您可以使用以下代码更改代码的最后部分:
dfW <- as.data.frame(matrix(nrow = 3 * length(sampledIDs), ncol = 3))
colnames(dfW) <- colnames(df) # make the column names the same
for(i in 1:length(sampledIDs)){ # notice the start index is changed from 2 to 1
#dfW <- rbind(dfW, df[df$ID == sampledIDs[i],])
dfW[(3*i-2):(3*i),] <- df[df$ID == sampledIDs[i],]
}
此更改可使您的代码运行得更快。让我知道它是怎么回事!
答案 1 :(得分:0)
如果您不知道最终大小,可以在需要时调整大小,但应在enum
循环中添加新的if条件。首先定义调整数据框大小的函数,如下所示:
for
然后启动double_rowsize <- function(df) {
mdf <- as.data.frame(matrix(, nrow = nrow(df), ncol = ncol(df)))
colnames(mdf) <- colnames(df)
df <- rbind(df, mdf)
return(df)
}
,初始大小为12(3次4):
dfW
最后在dfW <- as.data.frame(matrix(nrow = 12, ncol = 3))
colnames(dfW) <- colnames(df)
循环中添加if
条件,以便在需要时调整数据框的大小:
for
您可以更改函数double_rowsize的详细信息,以使用不同的数字更改数据框大小,而不是2,如果其他任何更好的方法。 2很常见,因为它在数组大小调整方面效果最佳。
祝你好运!