从查找表

时间:2015-04-28 17:52:28

标签: r replace dataframe

我有一个具有唯一ID的数据集和一个相应的路径字段,其中路径是连续的事件数(想想:购买的item1,item2,item3)。

以下是开发一些简单示例数据的一些代码:

PathStackOverflow <- c("a,b,c","b,c","a,d,e","d,c","e","a,e","a,b,c,e")
PathStackOverflow
[1] "a,b,c"   "b,c"     "a,d,e"   "d,c"     "e"       "a,e"     "a,b,c,e"
PathID <- c(123,144,156,133,153,122,169)
PathID
[1] 123 144 156 133 153 122 169
StackOverflowDF <- cbind(PathID,PathStackOverflow)
StackOverflowDF <- data.frame(cbind(PathID,PathStackOverflow))
View(StackOverflowDF)


PathID PathStackOverflow
1    123             a,b,c
2    144               b,c
3    156             a,d,e
4    133               d,c
5    153                 e
6    122               a,e
7    169           a,b,c,e

实际的数据框有大约350,000个观测值,所以如果有一个计算速度快的解决方案就会很棒!

某些路径值(例如a或e)需要根据查找表完全删除。例如,让我们说我要删除上面带有b和d的所有记录。我想为b和d定义一个向量,然后从列中删除它的所有实例,以便最终结果如下:

 PathID PathStackOverflow
1    123             a,c
2    144               c
3    156             a,e
4    133               c
5    153               e
6    122             a,e
7    169           a,c,e

保留列和数据帧的完整性非常重要,因为下一步是cSplit,我可以用逗号分割路径并运行每个外观的概率和频率。值。

到目前为止,我已经尝试过一系列可怕的低效步骤:

  1. 在ifelse中使用grepl来标记路径的每个实例的记录 价值需要删除
  2. 然后运行cSplit分成几列我尝试用plyr进行行级拆分/合并操作,以查找每行中的列是否具有该值,如果是,则删除它们并重新组合该行原版的。
  3. 但是还没有能够解决这个问题。此外,我认为这种方法效率不高,必须有一种方法可以从原始的连续列中删除字符串。

    还尝试了Gsub方法:

    StackOverflowDF$ID <- gsub(',+b', '', StackOverflowDF$PathStackOverflow)
    StackOverflowDF$ID <- gsub('b+,', '', StackOverflowDF$PathStackOverflow)
    

    这似乎工作得更好但是我的代码效率很低,因为我不得不为每个要删除的字符和每个逗号组合复制粘贴多行。

    我认为正确的解决方案将是某种辅助功能,可以将字符串向量移除,例如RemoveChars&lt; - c(&#34; b&#34;,&#34; d&#34;)然后为每种类型的逗号组合执行gSub操作?不确定这是否是继续进行的最佳方式,即使是,如何遍历每个查找表值。

    非常感谢有关如何进行此操作的任何帮助。

2 个答案:

答案 0 :(得分:2)

也许你可以试试这样的东西

library(data.table)
PathStackOverflow <- c("a,b,c","b,c","a,d,e","d,c","e","a,e","a,b,c,e")
PathID <- c(123,144,156,133,153,122,169)
StackOverflowDT <- data.table(PathID,PathStackOverflow)

# Remove any unneeded values
StackOverflowDT[, PathStackOverflow := gsub("b|d", "", PathStackOverflow)]
# Remove any repeating commas
StackOverflowDT[, PathStackOverflow := gsub(",+", ",", PathStackOverflow)]
# Remove any beginning or ending commas
StackOverflowDT[, PathStackOverflow := gsub("^,|,$", "", PathStackOverflow)]

StackOverflowDT
   PathID PathStackOverflow
1:    123               a,c
2:    144                 c
3:    156               a,e
4:    133                 c
5:    153                 e
6:    122               a,e
7:    169             a,c,e

对于查找表,您可以轻松地扩展第一个gsub,其内容如下:

paste(c("b", "d", "someotherword"), collapse = "|")

如果您没有使用data.table之前我肯定会推荐github wiki上的有用文档。希望有所帮助。

答案 1 :(得分:1)

您可以尝试使用更一般的模式gsub

df = StackOverflowDF  #sorry this is a long name

transform(df, new=gsub(',[b|d]|[b|d],','',df$PathStackOverflow))
#  PathID PathStackOverflow   new
#1    123             a,b,c   a,c
#2    144               b,c     c
#3    156             a,d,e   a,e
#4    133               d,c     c
#5    153                 e     e
#6    122               a,e   a,e
#7    169           a,b,c,e a,c,e