删除R中String中的重复元素

时间:2017-02-14 14:44:57

标签: r string

我在删除字符串中的重复元素时遇到了一些问题。 我的数据与此类似:

idvisit     path
1           1,16,23,59
2           2,14,14,19
3           5,19,23,19
4           10,10
5           23,23,27,29,23

我有一个包含唯一ID的列和一个包含网页导航路径的列。 右栏包含一些案例,其中页面刚重新加载,页面被跟踪两次甚至更多。 页面用逗号分隔并保存为因子。 我的问题是,我不想连续多个页面,所以数据应该是这样的。

idvisit     path
1           1,16,23,59
2           2,14,19
3           5,19,23,19
4           10
5           23,27,29,23

应删除彼此相邻的多个页面。我知道如何使用regexpressions删除特定的多个数字,但我有大约20,000个不同的页面,并且不能为所有这些页面执行此操作。 对于我的问题,有没有人有解决方案或提示?

由于 塞巴斯蒂安

2 个答案:

答案 0 :(得分:5)

我们可以使用tidyverse。使用separate_rows拆分路径'由分隔符(,)变换以转换为长格式,然后按' idvisit'分组,我们paste运行长度编码values

library(tidyverse)
separate_rows(df1, path) %>%
       group_by(idvisit) %>%
       summarise(path = paste(rle(path)$values, collapse=","))
# A tibble: 5 × 2
#  idvisit        path
#    <int>       <chr>
#1       1  1,16,23,59
#2       2     2,14,19
#3       3  5,19,23,19
#4       4          10
#5       5 23,27,29,23

base R选项

df1$path <- sapply(strsplit(df1$path, ","), function(x) paste(rle(x)$values, collapse=","))

注意:如果&#39;路径&#39;列为factor类,在作为参数传递给character之前转换为strsplit,即strsplit(as.character(df1$path), ",")

答案 1 :(得分:1)

使用stringr包,功能:str_replace_all,我认为使用以下正则表达式获取您想要的内容:([0-9]+),\\1然后将其替换为\\1(我们需要改变\特殊字符:

library(stringr)
> str_replace_all("5,19,23,19", "([0-9]+),\\1", "\\1")
[1] "5,19,23,19"
> str_replace_all("10,10", "([0-9]+),\\1", "\\1")
[1] "10"
> str_replace_all("2,14,14,19", "([0-9]+),\\1", "\\1")
[1] "2,14,19"

您可以以数组形式使用它:x <- c("5,19,23,19", "10,10", "2,14,14,19")然后:

str_replace_all(x, "([0-9]+),\\1", "\\1")
[1] "5,19,23,19" "10"         "2,14,19"

或使用sapply

result <- sapply(x, function(x) str_replace_all(x, "([0-9]+),\\1", "\\1"))

然后:

> result
  5,19,23,19        10,10   2,14,14,19 
"5,19,23,19"         "10"    "2,14,19" 

备注

第一行是属性信息:

> str(result)
Named chr [1:3] "5,19,23,19" "10" "2,14,19"
- attr(*, "names")= chr [1:3] "5,19,23,19" "10,10" "2,14,14,19"

如果您不想看到它们(它不会影响结果),请执行以下操作:

attributes(result) <- NULL

然后,

> result
[1] "5,19,23,19" "10"         "2,14,19"   

有关使用的正则表达式的说明:([0-9]+),\\1

  1. ([0-9]+):以()分隔的第1组开头,找到任何数字(至少一个)
  2. ,:然后是一个标点符号:,(我们可以在此处包含空格,但原始示例仅使用此字符作为分隔符)
  3. \\1:然后是与组1相同的字符串,即:重复的数字。如果这种情况没有发生,那么模式就不匹配了。
  4. 然后,如果模式匹配,则用变量\\1的值替换它,即数字第一次出现在匹配的模式中。

    如何处理多个重复的号码,例如2,14,14,14,19?:

    只需使用这个正则表达式:([0-9]+)(,\\1)+,然后当至少有一个重复分隔符(右)和数字时匹配。您可以使用此regex101.com尝试其他可能性(在MHO中,它比其他在线正则表达式检查器更友好)。

    我希望这对您有用,这是一个灵活的解决方案,您只需要根据您需要的模式进行调整。