首页 > 解决方案 > id被分配给多个类别如何删除行所以id在r中只有一个类别

问题描述

我正在使用 R 并且需要一些帮助。我有一个巨大的数据集,其中 id 分配给多个类别。我想删除行,所以 id 只有一个类别。逻辑如下:如果 id 仅分配给“已分配”列中的一个类别,则不要删除任何行(参见 id 2),但是当 id 分配给“已分配”列中的多个类别时,删除它具有的行“Banana”,除非“Banana”的行数多于“Apple”的删除行数(参见 id 3)。如果我可以在单独的数据框中获取我删除的记录,那就太好了。

这是我所拥有的

df <- data.frame(ID=c(1,1,1,2,2,3,3,3,4,4), 
                 Date=c("04-01-2020", "05-01-2020", "06-01-2020", "04-01-2020",
                 "05-01-2020", "04-01-2020", "05-01-2020", "06-01-2020",
                 "05-01-2020", "06-01-20202"),
                 Assigned = c("Apple", "Banana","Apple","Apple", "Apple",
                             "Apple","Banana","Banana", "Apple", "Banana"))

这就是我想要的

df1 <-  data.frame(ID=c(1,1,2,2,3,3,4), 
                   Date=c("04-01-2020", "06-01-2020", "04-01-2020",
                          "05-01-2020", "05-01-2020", "06-01-2020",
                          "05-01-2020"),
                   Assigned = c("Apple", "Apple","Apple", "Apple",
                                "Banana","Banana", "Apple"))
                           

另外,如何轻松获取 ID 具有多个类别的行(获取除 id 2 之外的所有行)。提前致谢。

标签: r

解决方案


你可以使用split-apply-bind这里的技术来获得守门员

do.call(rbind, lapply(split(df, df$ID), function(x) {
                 x[x$Assigned == names(which.max(table(x$Assigned))),]
}))
#>     ID       Date Assigned
#> 1.1  1 04-01-2020    Apple
#> 1.3  1 06-01-2020    Apple
#> 2.4  2 04-01-2020    Apple
#> 2.5  2 05-01-2020    Apple
#> 3.7  3 05-01-2020   Banana
#> 3.8  3 06-01-2020   Banana
#> 4    4 05-01-2020    Apple

和拒绝:

do.call(rbind, lapply(split(df, df$ID), function(x) {
                 x[x$Assigned != names(which.max(table(x$Assigned))),]
               }))
#>   ID        Date Assigned
#> 1  1  05-01-2020   Banana
#> 3  3  04-01-2020    Apple
#> 4  4 06-01-20202   Banana

以及每个 ID 具有多个类别的行的索引:

as.integer(which(do.call(c, lapply(split(df, df$ID), function(x) {
     rep(length(table(x$Assigned)) > 1, nrow(x))
 }))))
#> [1]  1  2  3  6  7  8  9 10

推荐阅读