我在删除字符串中的重复元素时遇到了一些问题。 我的数据与此类似:
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个不同的页面,并且不能为所有这些页面执行此操作。 对于我的问题,有没有人有解决方案或提示?
由于 塞巴斯蒂安
答案 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
([0-9]+)
:以()
分隔的第1组开头,找到任何数字(至少一个),
:然后是一个标点符号:,
(我们可以在此处包含空格,但原始示例仅使用此字符作为分隔符)\\1
:然后是与组1相同的字符串,即:重复的数字。如果这种情况没有发生,那么模式就不匹配了。然后,如果模式匹配,则用变量\\1
的值替换它,即数字第一次出现在匹配的模式中。
如何处理多个重复的号码,例如2,14,14,14,19
?:
只需使用这个正则表达式:([0-9]+)(,\\1)+
,然后当至少有一个重复分隔符(右)和数字时匹配。您可以使用此regex101.com尝试其他可能性(在MHO中,它比其他在线正则表达式检查器更友好)。
我希望这对您有用,这是一个灵活的解决方案,您只需要根据您需要的模式进行调整。