gpt4 book ai didi

R-数据框一列中的值在其他列中出现了多少次? (最好不使用 for 循环)

转载 作者:行者123 更新时间:2023-12-02 04:37:11 26 4
gpt4 key购买 nike

我已经为这个问题苦苦挣扎了一段时间,所以我希望有人能帮我找到一个更省时的解决方案。所以,我有一个像这样的 ID 数据框:

IDinsurer<-c(rep(11,3),rep(12,2),rep(11,2),rep(13,2),11)
ClaimFileNum<-c(rep('AA',3),rep('BB',2),rep('CC',2),rep('DD',2),'EE')
IDdriver<-c(rep(11,3),rep(12,2),rep(21,2),rep(13,2),11)
IDclaimant<-c(31,11,32,12,33,11,34,13,11,11)
IDclaimdriver<-c(41,11,32,12,11,21,34,13,12,11)
dt<-data.frame(ClaimFileNum,IDinsurer,IDdriver,IDclaimant,IDclaimdriver)

ClaimFileNum IDinsurer IDdriver IDclaimant IDclaimdriver
1 AA 11 11 31 41
2 AA 11 11 11 11
3 AA 11 11 32 32
4 BB 12 12 12 12
5 BB 12 12 33 11
6 CC 11 21 11 21
7 CC 11 21 34 34
8 DD 13 13 13 13
9 DD 13 13 11 12
10 EE 11 11 11 11

我想做的是计算个人 IDinsurer 在其他角色(即不作为保险公司)中出现的不同 claim 文件 (ClaimFileNum) 的数量。因此,对于每个 IDinsurer,我只想要 claim 文件的数量,他的 ID 出现在 IDdriver、IDclaimant 或 IDclaimsriver 中,同时他不是给定 claim 文件的 IDinsurer。例如,IDinsurer==11 与所有 ClaimFileNums 一起出现,但仅在“BB”和“DD”上他不是 IDinsurer,这意味着我希望我的程序返回 2。所以这就是我希望最终数据框的样子:

   ClaimFileNum IDinsurer IDdriver IDclaimant IDclaimdriver N
1 AA 11 11 31 41 2
2 AA 11 11 11 11 2
3 AA 11 11 32 32 2
4 BB 12 12 12 12 1
5 BB 12 12 33 11 1
6 CC 11 21 11 21 2
7 CC 11 21 34 34 2
8 DD 13 13 13 13 0
9 DD 13 13 11 12 0
10 AA 11 11 11 11 2

所以这就是我到目前为止能够想出的:

1)对于其他三个角色(IDdriver、IDclaimant、IDclaimsdriver)中的每一个,我单独计算了一个新列,其中包含数字,显示特定 ID 出现在该角色中的 claim 文件数量,不包括 claim 文件的情况,在这些情况下,他们也是保险公司(然而,对于 IDclaimsdriver,排除 ID 与 IDclaimant 或 IDdriver 匹配的情况更有意义)。这是 IDdriver 计数的代码:

count.duplicates <- function(dt){                                 #removing duplicated columns and adding a column with the frequency of duplications
x <- do.call('paste', c(dt[,c("ClaimFileNum","IDdriver")], sep = '\r'))
ox <- order(x)
rl <- rle(x[ox])
cbind(dt[ox[cumsum(rl$lengths)],,drop=FALSE],count = rl$lengths)

}
dt<-count.duplicates(dt)
dt<-data.table(dt)
dt[,same:=ifelse(dt$IDinsurer==dt$IDdriver,0,1)]
dt[,N_IDdriver:=sum(same,na.rm = T),by=list(IDdriver)]
dt[,same:=NULL]

setorder(dt,ClaimFileNum)
dt<-expandRows(dt,"count")
dt<-as.data.frame(dt)

这是我的示例在所有三个计数之后的输出:

       ClaimFileNum IDinsurer IDdriver IDclaimant IDclaimdriver N_IDdriver N_IDclaimant N_IDclaimdriver
1 AA 11 11 31 41 0 1 1
2 AA 11 11 11 11 0 1 1
3 AA 11 11 32 32 0 1 0
4 BB 12 12 12 12 0 0 1
5 BB 12 12 33 11 0 1 1
6 CC 11 21 11 21 1 1 0
7 CC 11 21 34 34 1 1 0
8 DD 13 13 13 13 0 0 0
9 DD 13 13 11 12 0 1 1
10 EE 11 11 11 11 0 1 1

2) 我现在首先在整个 IDinsurer 列上使用 for 循环,以使用匹配函数检查 insurerID[i] 是否出现在其他三个角色 ID 中的任何一个中。如果找到匹配项,我只需将相应 N_ 列中的计数添加到总计数中。这是我的 for 循环:

total<-length(dt$IDinsurer)
for(i in 1:total) {
j<-match(dt$IDinsurer[i],dt$IDdriver,nomatch=0);
k<-match(dt$IDinsurer[i],dt$IDclaimant,nomatch=0);
l<-match(dt$IDinsurer[i],dt$IDclaimdriver,nomatch=0);
dt$N[i]<-ifelse(j==0,0,N_IDdriver[j])+ifelse(k==0,0,N_IDclaimant[k])+ifelse(l==0,0,N_IDclaimdriver[l]);
}

虽然这种方法为我提供了我需要的所有信息,但不幸的是它非常缓慢,尤其是在像我必须处理的那样有超过 200 万个案例的数据集上。我确信一定有一个更优雅的解决方案,我一直在试图弄清楚如何使用一些更高效的工具(如 data.table)来实现它,但我就是无法掌握它。

编辑:我决定在我的例子中尝试我的问题的两个答案,并将它们与我的尝试进行比较,所以这里是计算时间:Thom Quinn 的 for 循环:0.15 秒,我的 for 循环:0.25 秒,bounyball 的方法:0.35 秒。

在 1,042,000 行数据集上使用我的循环只用了不到 10 个小时。

最佳答案

Match 是出了名的慢,在这种情况下不需要。事实上,你已经用英语解决了这个问题,你只需要将它翻译成计算机行话!

So for each IDinsurer I only want the count of claim files, where his ID appeared in either IDdriver, IDclaimant or IDclaimdriver while at the same time he isn't the IDinsurer of the given claimfile

所以,让我们这样做吧。在伪代码中:

for each unique IDinsurer:
count when IDdriver OR IDclaimant OR IDclaimdriver AND NOT IDinsurer

在 R 中,这是:

for(i in unique(dt$IDinsurer)){
index <- dt$IDinsurer != i & (dt$IDdriver == i | dt$IDclaimant == i | dt$IDclaimdriver == i)
dt[dt$IDinsurer == i, "N"] <- sum(index)
}

关于R-数据框一列中的值在其他列中出现了多少次? (最好不使用 for 循环),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41229105/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com