当某些行重复时,在data.frame中选择行

时间:2017-03-12 16:11:47

标签: r

我有以下玩具数据集

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的概率选择,那么听起来也很棒!)

2 个答案:

答案 0 :(得分:1)

代码速度很低,因为您在for循环的每个循环中调整数据框的大小。这是我的建议。创建一个数据框,其最终大小为数据框dfWfor循环之前的大小。然后将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很常见,因为它在数组大小调整方面效果最佳。

祝你好运!