【问题标题】:Cleaning redundant chronological team data in R在 R 中清理冗余的按时间顺序排列的团队数据
【发布时间】:2014-11-17 00:32:54
【问题描述】:

我有一个如下所示的数据集(“dat”):

Team     Person1    Person2     Person3     Person4     Person5     Person6     Person7     Person8
1195880  37506459   37470284    NA          NA          NA          NA          NA          NA
6592553  30113892   33080542    21537647    32294183    NA          NA          NA          NA
6593701  697917     22860611    NA          NA          NA          NA          NA          NA
9595288  24433487   32370872    11522125    363290      8877040     22313302    32432767    NA
1595882  12318169   25645992    NA          NA          NA          NA          NA          NA
6595978  24433487   32370872    11522125    363290      8877040     22313302    32432767    NA
7545798  24433487   32370872    11522125    363290      8877040     22313302    NA          NA
2095820  12318169   25645992    37506459 

dat 按时间顺序排列。从数据集的开头(即最早的时间点)开始,我想消除以下情况之一:a)完全相同的一组人在以后的时间点组建了一个团队和/或 b)一个子集一个以前组建的团队走到了一起。在这两种情况下,我都希望保留较早的分组并消除较新的分组。

例如,在我的示例数据集中,团队 6595978 和 7545798 都应该被淘汰;团队 6595978 是团队 9595288(之前按时间顺序列出)的精确复制品,团队 7545798 是团队 9595288 的子集。但是,团队 2095820 不应被淘汰;虽然团队 2095820 包含之前列出的团队 1595882 的所有成员,但团队 2095820 应该保留,因为添加了一个新成员,人 37506459。

欢迎任何/所有建议。提前致谢!

真诚地, 艾米

【问题讨论】:

    标签: r data-cleaning


    【解决方案1】:

    你有多少行?这是解决问题的一种相当低效的方法,但如果您的数据大小合理,它可能会起作用。

    bad<-numeric();
    for(i in 2:nrow(dd)) {
        for(j in 1:(i-1)) {
            if (all(dd[i,-1] %in% dd[j, -1])) {
                bad <- c(bad, i)
                break;
            }
        }
    }
    dd[bad, ]
    #      Team  Person1  Person2  Person3 Person4 Person5  Person6  Person7 Person8
    # 6 6595978 24433487 32370872 11522125  363290 8877040 22313302 32432767      NA
    # 7 7545798 24433487 32370872 11522125  363290 8877040 22313302       NA      NA
    

    这是使用reshape2 库的另一个想法。在这里,我们要确保 Team 列是一个因子,其顺序由行给出,而不是按数字/字母顺序排序。

    dd$Team<-factor(dd$Team, levels=unique(dd$Team))
    
    library(reshape2)
    mm<-acast(melt(dd, "Team", na.rm=T), Team~value, length)
    bad<-combn(1:nrow(mm), 2, function(z) {
        sum(mm[z[1],] == 1 & mm[z[1],] == mm[z[2],]) == sum(mm[z[2],]==1)
    })
    bad<-unique(combn(1:nrow(mm), 2)[2, bad])
    levels(dd$Team)[bad]
    # [1] "6595978" "7545798"
    

    【讨论】:

    • (+1) 用于combn 方法。我从lapply(combn(nrow(dat), 2, simplify = FALSE), function(x) dat[x,]) 开始并尝试以这种方式进行比较,并在各列中使用duplicated
    • @RichardScriven 是的,combn 有它自己的 function= 参数,你可以使用它而不是包裹在 lapply 中,这很好。
    • @MrFlick 感谢您的建议!我都试过了。第一个建议仍在运行(可能是因为我的数据集中有超过 80,000 行)。至于第二个建议,当我输入 mm&lt;-acast(melt(dd, "Team", na.rm=T), Team~value, length) 时,我收到以下错误消息:Error: n must be a positive integer In addition: Warning message: In split_indices(.group, .n) : NAs introduced by coercion
    • @waxattax 我无法复制您在样本数据中遇到的错误,所以我不确定这只是大小问题还是什么问题。一个人出现在多个团队中的频率如何?您可以通过首先对个人出现一次的行进行子集化来减少问题的大小。如果这个数字明显小于 80,000,那将大大减少计算时间,因为这些建议都大致是 O(n^2)
    猜你喜欢
    • 1970-01-01
    • 2017-12-16
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多