在 R 中删除 2 个向量的部分重叠部分
Dropping partially overlapping parts of 2 vectors in R
我想知道是否可以删除 n1
字符向量中 与 中的元素部分重叠的部分f1
公式。
例如,在n1
中,我们看到"chyes"
&"bmi:chyes"
与f1
中的ch
部分重叠。
因此在desired_output
中,我们要删除其中的"ch"
部分。因为 n1
中的其他元素要么与 f1
中的元素完全重叠(例如 bmi
),要么不存在于 f1
中(例如 intrcpt
) , 我们保持不变。
我尝试了以下解决方案,但无法获得我想要的输出。
是否可以在 BASE R
或 tidyvesrse 中获取我的 desired_output
?
f1 <- yi~ bmi*ch
n1 <- c("intrcpt","bmi","chyes","bmi:chyes")
desired_output <- c("intrcpt","bmi","yes","bmi:yes")
### Current unsuccessful solution:
foo <- function(fmla, vec) {
v1 <- all.vars(fmla)
v2 <- setdiff(vec, v1)
v1 <- paste0('^', v1)
v3 <- sub(paste(v1, collapse = "|"), "", v2)
vec[vec %in% v2] <- v3
vec
}
### EXAMPLE OF USE:
foo(f1, n1)
# "intrcpt" "bmi" "chyes" "bmi:chyes"
这个函数可以做你想做的,但我同意@Onyambu 的观点,值得考虑你的潜在问题是否真的需要字符串操作。
f <- function(fm, nm) {
vars <- vapply(attr(terms(fm), "variables"), deparse, "")[-1L]
subpat <- paste0(gsub("([()])", "\\\1", vars), collapse = "|")
l <- rapply(strsplit(nm, ":"), sub, how = "list",
perl = TRUE,
pattern = sprintf("^(?!(%1$s)$)(%1$s)(.+)$", subpat),
replacement = "\3")
vapply(l, paste0, "", collapse = ":")
}
fm1 <- yi ~ bmi * ch
nm1 <- c("intrcpt", "bmi", "chyes", "bmi:chyes")
f(fm1, nm1)
[1] "intrcpt" "bmi" "yes" "bmi:yes"
fm2 <- yi ~ bmi * factor(ch)
nm2 <- c("intrcpt", "bmi", "factor(ch)yes", "bmi:factor(ch)yes")
f(fm2, nm2)
[1] "intrcpt" "bmi" "yes" "bmi:yes"
fm3 <- gi ~ 0 + time:pub_type + time_wk_whn + time_wk_btw
nm3 <- c("time_wk_whn", "time_wk_btw", "timePost-test 1:pub_typejournal", "timePost-test 2:pub_typejournal")
f(fm3, nm3)
[1] "time_wk_whn" "time_wk_btw"
[3] "Post-test 1:journal" "Post-test 2:journal"
我想知道是否可以删除 n1
字符向量中 与 中的元素部分重叠的部分f1
公式。
例如,在n1
中,我们看到"chyes"
&"bmi:chyes"
与f1
中的ch
部分重叠。
因此在desired_output
中,我们要删除其中的"ch"
部分。因为 n1
中的其他元素要么与 f1
中的元素完全重叠(例如 bmi
),要么不存在于 f1
中(例如 intrcpt
) , 我们保持不变。
我尝试了以下解决方案,但无法获得我想要的输出。
是否可以在 BASE R
或 tidyvesrse 中获取我的 desired_output
?
f1 <- yi~ bmi*ch
n1 <- c("intrcpt","bmi","chyes","bmi:chyes")
desired_output <- c("intrcpt","bmi","yes","bmi:yes")
### Current unsuccessful solution:
foo <- function(fmla, vec) {
v1 <- all.vars(fmla)
v2 <- setdiff(vec, v1)
v1 <- paste0('^', v1)
v3 <- sub(paste(v1, collapse = "|"), "", v2)
vec[vec %in% v2] <- v3
vec
}
### EXAMPLE OF USE:
foo(f1, n1)
# "intrcpt" "bmi" "chyes" "bmi:chyes"
这个函数可以做你想做的,但我同意@Onyambu 的观点,值得考虑你的潜在问题是否真的需要字符串操作。
f <- function(fm, nm) {
vars <- vapply(attr(terms(fm), "variables"), deparse, "")[-1L]
subpat <- paste0(gsub("([()])", "\\\1", vars), collapse = "|")
l <- rapply(strsplit(nm, ":"), sub, how = "list",
perl = TRUE,
pattern = sprintf("^(?!(%1$s)$)(%1$s)(.+)$", subpat),
replacement = "\3")
vapply(l, paste0, "", collapse = ":")
}
fm1 <- yi ~ bmi * ch
nm1 <- c("intrcpt", "bmi", "chyes", "bmi:chyes")
f(fm1, nm1)
[1] "intrcpt" "bmi" "yes" "bmi:yes"
fm2 <- yi ~ bmi * factor(ch)
nm2 <- c("intrcpt", "bmi", "factor(ch)yes", "bmi:factor(ch)yes")
f(fm2, nm2)
[1] "intrcpt" "bmi" "yes" "bmi:yes"
fm3 <- gi ~ 0 + time:pub_type + time_wk_whn + time_wk_btw
nm3 <- c("time_wk_whn", "time_wk_btw", "timePost-test 1:pub_typejournal", "timePost-test 2:pub_typejournal")
f(fm3, nm3)
[1] "time_wk_whn" "time_wk_btw"
[3] "Post-test 1:journal" "Post-test 2:journal"