我有一个RIS(文本(文件,大致如下所示:
mylist <- c("TI - a", "AU - b", "ER -", " ",
"TI - c", "AU - d", "ER -", " ",
"TI - e", "AU - f", "ER -")
我想插入一个运行ID标签如下
mylist_with_ids <- c("TI - a", "AU - b", "ID - 1", "ER -", " ",
"TI - c", "AU - d", "ID - 2", "ER -", " ",
"TI - e", "AU - f", "ID - 3", "ER -")
我最初的方法是编写一个stringr::str_replace
循环,在其中我预先生成ID列表。
cc_id_replace <- paste0("ID - ", 1:3, "nER -")
for (i in 1:3) {
mylist_with_ids <- str_replace(mylist, "^ER -", cc_id_replace[i])
}
当然,这不起作用的原因不止一个。还有什么更好的方法呢?(存在许多正则表达式和多个数组问题,但到目前为止我还无法找到答案。(
您可以尝试:
list[list == "ER -"] <- paste("ID -", seq_along(which(list == "ER -")), "nER -")
我认为这里可以使用游程编码。
(顺便说一句:我不喜欢使用list
作为变量名,因为它是一个经常使用的R函数。虽然R很清楚你在引用时的意思,但这可能会被愚弄,并且故障排除会有问题。所以我在这里将其命名为mylist
。(
mylist <- c("TI - a", "AU - b", "ER -", " ",
"TI - c", "AU - d", "ER -", " ",
"TI - e", "AU - f", "ER -")
non_ER_runs <- rle(mylist == "ER -")
non_ER_runs
# Run Length Encoding
# lengths: int [1:6] 2 1 3 1 3 1
# values : logi [1:6] FALSE TRUE FALSE TRUE FALSE TRUE
RLE告诉我们每个类别中有多少人。对我们来说,分类是"匹配和不匹配"。这里的$values
向量告诉我们,第一个元素不匹配(FALSE
(,并且有两个元素。第二批确实匹配(TRUE
(,并且是一个长的。等等
inds <- cumsum(non_ER_runs$lengths)
newlist <- mapply(function(a,b) mylist[a:b], c(1, 1+head(inds, n=-1)), inds)
newlist
# [[1]]
# [1] "TI - a" "AU - b"
# [[2]]
# [1] "ER -"
# [[3]]
# [1] " " "TI - c" "AU - d"
# [[4]]
# [1] "ER -"
# [[5]]
# [1] " " "TI - e" "AU - f"
# [[6]]
# [1] "ER -"
好吧,我们把每一批都分解成了自己的向量。再次使用rle
的返回,我们可以只选择要附加内容的元素:
newlist[ non_ER_runs$values ]
# [[1]]
# [1] "ER -"
# [[2]]
# [1] "ER -"
# [[3]]
# [1] "ER -"
Map(function(vec, vec2) c(vec, vec2),
newlist[ non_ER_runs$values ],
sprintf("ID - %i", seq_along(newlist[ non_ER_runs$values ])))
# [[1]]
# [1] "ER -" "ID - 1"
# [[2]]
# [1] "ER -" "ID - 2"
# [[3]]
# [1] "ER -" "ID - 3"
现在只需要用新元素替换列表元素,然后unlist
就可以了。
newlist[ non_ER_runs$values ] <-
Map(function(vec, vec2) c(vec, vec2),
newlist[ non_ER_runs$values ],
sprintf("ID - %i", seq_along(newlist[ non_ER_runs$values ])))
newlist <- unlist(newlist)
newlist
# [1] "TI - a" "AU - b" "ER -" "ID - 1" " "
# [6] "TI - c" "AU - d" "ER -" "ID - 2" " "
# [11] "TI - e" "AU - f" "ER -" "ID - 3"
ris <- c("TI - a", "AU - b", "ER -", " ",
"TI - c", "AU - d", "ER -", " ",
"TI - e", "AU - f", "ER -")
另一个建议是对循环使用dirty;(
1.找到要在前面插入ID元素的位置(这里使用一点正则表达式(。使用pos
矢量生成正确数量的ID:
pos <- grep("^ER", ris)
ids <- paste0("ID = ", seq_along(pos))
2.循环所有位置,插入、粘贴、重复(并更新pos
(:
for (i in seq_along(pos)) {
ris <- c(ris[1:(pos[i]-1)], ids[i], ris[pos[i]:length(ris)] )
pos <- pos + 1
}
ris
退货:
[1] "TI - a" "AU - b" "ID = 1" "ER -"
[5] " " "TI - c" "AU - d" "ID = 2"
[9] "ER -" " " "TI - e" "AU - f"
[13] "ID = 3" "ER -"