如果单元格的列名出现在同一行的前一个单元格中,则标记单元格的速度更快

时间:2018-02-28 07:53:51

标签: r dataframe

  • 我有一个大数据框(~280000行x 1200列),每行代表一篮子项目。
  • 第一列有篮子ID。
  • 接下来的~120列具有4位数的项目代码(篮子中存在的项目之一)或者是空白的(对于篮子的所有项目之后的剩余120个单元格)。
  • 后续列(从121到1200)各自使用项目Universe中唯一的4位数项目代码之一命名。所有这些列都是空白的。

现在,我想标记这些列(121到1200)中的单元格,如果该项目(列名称)出现在该行/篮子中。

以下是数据帧的较小版本(df);

df <- data.frame(BasketID = c("001", "002"),
                 Item1 = c(1001, 1002), Item2 = c(1002,""), Item3 = "",
                 `1001` = "", `1002` = "", `1003` = "", check.names=F)

BasketID   Item1   Item2   Item3   ...   1001   1002   1003
001        1001    1002
002        1003

以下是我的要求;

BasketID   Item1   Item2   Item3   ...   1001   1002   1003
001        1001    1002                  tag    tag
002        1003                                        tag

我写了以下for循环来实现上述目的;

for (i in rownames(df)) {  

    for (j in colnames(df[,121:1200])) {  

        if (j %in% df[i,121:1200]) { 

            df[i,j] <- "tag"
        }
    }
}

但是,由于数据帧很大,上面的命令将永远运行,迫使我中途中止。有没有更有效的方法来做到这一点?非常感谢v。提前!!

1 个答案:

答案 0 :(得分:1)

使用data.table包可能更容易完成。使用melt转换为长格式。具有有效值的子集。然后使用长度&gt;转动数据。 0为fun.aggregate

library(data.table)
dcast.data.table(
    melt(setDT(df), id.vars="BasketID"),
    BasketID ~ value,
    function(x) length(x) > 0,
    subset=.(value!=""))

#the join the results with original dataset to get OP's desired format
tags[df, on=.(BasketID)]

#    BasketID  1001  1002  1003 Item1 Item2 Item3
# 1:      001  TRUE  TRUE FALSE  1001  1002      
# 2:      002 FALSE FALSE  TRUE  1003            

数据:

df <- data.frame(BasketID = c("001", "002"),
    Item1 = c(1001, 1003), Item2 = c(1002,""), Item3 = "")