r - 在 r 中,使用字符串,就像我输入它一样
问题描述
我正在处理 r 的一个方面,这确实让我感到困惑。我构建的是一行代码调用 str_remove 保存为字符串。如果我将该字符串复制粘贴到我想使用这行代码的位置,它会按预期完美运行。但是我无法让 r 正确解释此代码。我曾尝试使用例如解析,但用于 str_remove 正则表达式的转义字符会引发错误。
有没有一种简单的方法可以将字符串视为一行输入的代码?
这是我的可重现示例:
制作玩具数据:
maf_list_context <- list(as.data.frame(cbind(c("ATTATCGAATT", "ATTATTTTAAA"), c("this one", "not that one"))),
as.data.frame(cbind(c("ATTACGTAATT", "ATTATTTTAAA"), c("this one too", "not that one either"))) )
maf_list_context <- lapply(maf_list_context, function(x)
{colnames(x) <- c("CONTEXT", "want_it")
return(x)
})
这个想法是上下文将是一个函数的参数并且它可以是灵活的,因此用户可以提供任意数量的以逗号分隔的感兴趣的上下文。这些将是 stringr 正则表达式,旨在在一串 11 个碱基中查找 DNA 中的特定上下文。例如,在这里我们可以使用两个感兴趣的上下文。下面的代码将这些组合在一起,形成一个表达式,供以后从列表中的数据框中选择适当的行时使用。
context <- "\\w{5}CG\\w{4}, \\w{4}CG\\w{5}"
contextvec <- unlist(str_split(context, pattern = ", "))
contextexpression <- c()
for(i in 1:length(contextvec)){
contextexpression <- paste0(contextexpression, "str_detect(x$CONTEXT, pattern = '", contextvec[i], "') |")
}
contextexpression <- str_remove(contextexpression, pattern = " \\|$")
“上下文表达式”现在是:
[1] "str_detect(x$CONTEXT, pattern = '\\w{5}CG\\w{4}') |str_detect(x$CONTEXT, pattern = '\\w{4}CG\\w{5}')"
如果我将这个表达式直接粘贴到 apply 中,它会完全按照我的意愿工作。
> lapply(maf_list_context, function(x){
+
+ x[str_detect(x$CONTEXT, pattern = '\\w{5}CG\\w{4}') |str_detect(x$CONTEXT, pattern = '\\w{4}CG\\w{5}'), ]
+
+ })
[[1]]
CONTEXT want_it
1 ATTATCGAATT this one
[[2]]
CONTEXT want_it
1 ATTACGTAATT this one too
但当然,如果我在那里使用字符串,它不会。
> lapply(maf_list_context, function(x){
+
+ x[contextexpression, ]
+
+ })
[[1]]
CONTEXT want_it
NA <NA> <NA>
[[2]]
CONTEXT want_it
NA <NA> <NA>
我尝试了许多不同的功能,但没有一个可以使这项工作。有没有办法让 r 解释这个字符串,就好像我直接输入它一样?
整个代表:
if (!require("stringr") {
install.packages("stringr", dependencies = TRUE)
library("stringr")
maf_list_context <- list(as.data.frame(cbind(c("ATTATCGAATT", "ATTATTTTAAA"), c("this one", "not that one"))),
as.data.frame(cbind(c("ATTACGTAATT", "ATTATTTTAAA"), c("this one too", "not that one either"))) )
maf_list_context <- lapply(maf_list_context, function(x){
colnames(x) <- c("CONTEXT", "want_it")
return(x)
})
context <- "\\w{5}CG\\w{4}, \\w{4}CG\\w{5}"
contextvec <- unlist(str_split(context, pattern = ", "))
contextexpression <- c()
for(i in 1:length(contextvec)){
contextexpression <- paste0(contextexpression, "str_detect(x$CONTEXT, pattern = '", contextvec[i], "') |")
}
contextexpression <- str_remove(contextexpression, pattern = " \\|$")
maf_list_select <- lapply(maf_list_context, function(x){
x[contextexpression, ]
})
解决方案
我不确定我是否完全遵循您希望输入的内容以及如何应用它,但您的问题似乎与您传递给子集运算符的内容有关,即x[<codehere>]
子集运算符需要一个逻辑向量。当您“粘贴表达式”时,您实际上是在粘贴一个被评估为逻辑向量的表达式,因此它可以正确地进行子集化。当您传递变量contextexpression
时,您实际上是在传递一个字符串。正如 R 所见:
x[ "str_detect(x$CONTEXT, pattern = '\\w{5}CG\\w{4}') |str_detect(x$CONTEXT, pattern = '\\w{4}CG\\w{5}')", ]
而不是(注意语法突出显示的差异):
x[ str_detect(x$CONTEXT, pattern = '\\w{5}CG\\w{4}') |str_detect(x$CONTEXT, pattern = '\\w{4}CG\\w{5}'), ]
您希望将每个上下文应用于列表的每个成员以获取逻辑向量,然后获取子集。
purrr::map2(maf_list_context, contextvec, ~.x[str_detect(.x$CONTEXT, .y), ])
如果您想将 中的每个项目与 中contextvec
的每个项目进行比较maf_list_context
,那么它有点复杂但可行。
purrr::map2(
maf_list_context,
purrr::map(
maf_list_context,
function(data){
purrr::reduce(contextvec,
function(prev, cond) str_detect(data$CONTEXT, cond) | prev,
.init = logical(length(contextvec))
)
}
),
~.x[.y]
)
可能有一种更有效的方法可以将匹配项与 中的项目短路maf_list_context
,但一般方法适用。str_detect
处理单个条件与单个maf_list
项目的比较。该reduce
调用将与contextvec
单个项目的所有比较结果组合maf_list_context
到单个布尔值中。内部map
遍历maf_list_context
. 外层map2
遍历由内层创建的布尔值列表,map
并maf_list_context
找到匹配的子集。
如果maf_list_context
有 n 个项目并且contextvec
有 m 个项目:
reduce
进行 m 次比较,得到 1 个值map
进行 n 次调用以reduce
产生 n 个值map2
对子集进行 n 次迭代maf_list_context
推荐阅读
- java - 我得到:selenium webdriver 项目中的分叉过程中出现错误
- php - PHP 爆炸函数行尾检测
- javascript - 如何在声明文件中使用可选依赖项中的类型?
- haskell - Do notation for monad in function return a different type
- javascript - ruby on rails 从 button_tag 调用 javascript 函数
- javafx - JavaFX ConcurrentModificationException 与 GridPane.get...Index()
- perl - 拆分不同的数字,计算出现次数并返回每个数字的百分比
- jquery - 如何对 jquery 数据表进行日期范围过滤?
- codeigniter - codeigniter,路线和语言
- django - Authenticating user problem with django-tenant-schema