今天,尽管我正在寻找解决方案,但我仍然面临一个无法独自解决的问题-在我看来,我的方法是错误的,还是在问类似问题之前没人问过。
我正在研究Markov归因,因此我得到的列的字符串如下所示:
A > B > B > C > B > A > C > B > A
等
...它是基于postgresql函数'string_agg'创建的。
我认为对我来说很重要的是分配一定数量的时间,以便每个字符串都出现在整个字符串中。为了明确起见,最终看起来像这样:
A1 > B1 > B2 > C1 > B3 > A2 > C2 > B4 > A3
存在三个主要挑战:
我想到的唯一的事情就是编写某种循环,但是直到完成为止,这似乎需要花费很多时间。
我还考虑过在PostgreSQL级别上解决它,但也找不到有效且简单的解决方案。
答案 0 :(得分:2)
以下是使用data.table
的粗略示例:
library(data.table)
# Example data:
data <- data.table(
s = c("A > B > B > C > B > A > C > B > A",
"A > B > B > C > B > A > C > B > C > D")
)
# Processing steps (can probably be shortened)
n <- strsplit(data[["s"]], " > ")
datal <- melt(n)
setDT(datal)
datal[, original_order := 1:.N
][, temp := paste0(value, 1:.N), by = .(L1, value)
][order(original_order), paste(temp, collapse = " > "), by = L1]
# Output:
L1 V1
1: 1 A1 > B1 > B2 > C1 > B3 > A2 > C2 > B4 > A3
2: 2 A1 > B1 > B2 > C1 > B3 > A2 > C2 > B4 > C3 > D1
答案 1 :(得分:2)
这里是仅使用基数R的函数。
请注意,如果您使用一组不同的正则表达式元字符,则使用函数参数metachar
(在函数体中默认为默认值)应该很容易。
count_seq <- function(x, sep = ">"){
metachar <- '. \ | ( ) [ { ^ $ * + ?'
sep2 <- if(grepl(sep, metachar)) paste0("\\", sep) else sep
y <- unlist(strsplit(x, sep2))
y <- trimws(y)
z <- ave(y, y, FUN = seq_along)
paste(paste0(y, z), collapse = sep)
}
x <- "A > B > B > C > B > A > C > B > A"
count_seq(x)
#[1] "A1>B1>B2>C1>B3>A2>C2>B4>A3"
count_seq(x, sep = " > ")
#[1] "A1 > B1 > B2 > C1 > B3 > A2 > C2 > B4 > A3"
y <- "A | B | B | C | B | A | C | B | A"
count_seq(y, sep = "|")
#[1] "A1|B1|B2|C1|B3|A2|C2|B4|A3"
答案 2 :(得分:1)
gsubfn vignette中描述了如何执行此操作。首先使用那里的代码,使用方法pword
和pre
定义原型对象fun
。 pre
初始化单词列表(存储遇到的每个单词的当前计数),fun
每次遇到新单词时都会对其进行更新,并且还会在单词后缀后加上返回后缀单词的计数。
已经定义了前面的内容,使用gsubfn
运行pword
。对于输入gsubfn
的每个组成部分,将首先运行pre
,然后对于正则表达式\\w+
的每个匹配项,gsubfn
将匹配项输入到fun
,运行fun
并将匹配项替换为fun
的输出。
我们假设要加一个后缀的单词由\w+
匹配,这是问题示例的情况,但是如果实际数据不同,则可能需要更改模式。
library(gsubfn)
s <- rep("A > B > B > C > B > A > C > B > A", 3) # sample input
pwords <- proto(
pre = function(this) { this$words <- list() },
fun = function(this, x) {
if (is.null(words[[x]])) this$words[[x]] <- 0
this$words[[x]] <- this$words[[x]] + 1
paste0(x, words[[x]])
}
)
gsubfn("\\w+", pwords, s)
给予:
[1] "A1 > B1 > B2 > C1 > B3 > A2 > C2 > B4 > A3"
[2] "A1 > B1 > B2 > C1 > B3 > A2 > C2 > B4 > A3"
[3] "A1 > B1 > B2 > C1 > B3 > A2 > C2 > B4 > A3"