在 R 函数中使用匿名函数
Using an anonymous function within a function in R
我这里有一个基因位点列表,其中包含编码为三位数字的等位基因,如 class 字符。我有几行代码来遍历列表并将所有实例转换为核酸碱基字母(即 A、C、G、T)。
my_allele_list = list(loc1 = c("001", "002"),
loc2 = c("001", "003"),
loc3 = c("004", "001"),
loc4 = c("003", "003"),
loc5 = c("001", "002"),
loc6 = c("002", "004"))
a = c("001", "002", "003", "004")
b = c("A", "C", "G", "T")
for(i in seq_along(a)) my_allele_list <-
lapply(my_allele_list, function(x) gsub(a[i], b[i], x))
my_allele_list
到目前为止一切顺利,但为了保持整洁,我想将这些行包装到一个函数中。
convert_alleles <- function(x){
a = c("001", "002", "003", "004")
b = c("A", "C", "G", "T")
for(i in seq_along(a)) x <-
lapply(x, function(x) gsub(a[i], b[i], x))
}
convert_alleles(my_allele_list)
my_allele_list
但是,正如您在第二遍中看到的那样,该函数不起作用 - 没有错误,只是没有对列表对象进行任何更改。我怀疑问题出在与 for 循环中的匿名函数发生冲突。有人可以解释问题所在并提出解决方案吗?
使用矢量化函数可能更容易,因为 str_replace
library(dplyr)
library(purrr)
library(stringr)
map(my_allele_list, ~ str_replace_all(.x, setNames(b, a)))
-输出
$loc1
[1] "A" "C"
$loc2
[1] "A" "G"
$loc3
[1] "T" "A"
$loc4
[1] "G" "G"
$loc5
[1] "A" "C"
$loc6
[1] "C" "T"
此外,如果它是固定匹配而不是示例中的部分匹配,请使用 setNames
创建命名向量并匹配并替换
map(my_allele_list, ~ unname(setNames(b, a)[.x]))
$loc1
[1] "A" "C"
$loc2
[1] "A" "G"
$loc3
[1] "T" "A"
$loc4
[1] "G" "G"
$loc5
[1] "A" "C"
$loc6
[1] "C" "T"
这也可以用 base R
-lapply
来完成
lapply(my_allele_list, \(x) unname(setNames(b, a)[x]))
$loc1
[1] "A" "C"
$loc2
[1] "A" "G"
$loc3
[1] "T" "A"
$loc4
[1] "G" "G"
$loc5
[1] "A" "C"
$loc6
[1] "C" "T"
在OP函数中,return
值应该是x
convert_alleles <- function(x){
a = c("001", "002", "003", "004")
b = c("A", "C", "G", "T")
for(i in seq_along(a)) x <-
lapply(x, function(x) gsub(a[i], b[i], x))
x
}
convert_alleles(my_allele_list)
$loc1
[1] "A" "C"
$loc2
[1] "A" "G"
$loc3
[1] "T" "A"
$loc4
[1] "G" "G"
$loc5
[1] "A" "C"
$loc6
[1] "C" "T"
注意:当我们运行函数时,它不会改变对象my_allele_list
。为此,我们分配回 (<-
)
my_allele_list <- convert_alleles(my_allele_list)
我这里有一个基因位点列表,其中包含编码为三位数字的等位基因,如 class 字符。我有几行代码来遍历列表并将所有实例转换为核酸碱基字母(即 A、C、G、T)。
my_allele_list = list(loc1 = c("001", "002"),
loc2 = c("001", "003"),
loc3 = c("004", "001"),
loc4 = c("003", "003"),
loc5 = c("001", "002"),
loc6 = c("002", "004"))
a = c("001", "002", "003", "004")
b = c("A", "C", "G", "T")
for(i in seq_along(a)) my_allele_list <-
lapply(my_allele_list, function(x) gsub(a[i], b[i], x))
my_allele_list
到目前为止一切顺利,但为了保持整洁,我想将这些行包装到一个函数中。
convert_alleles <- function(x){
a = c("001", "002", "003", "004")
b = c("A", "C", "G", "T")
for(i in seq_along(a)) x <-
lapply(x, function(x) gsub(a[i], b[i], x))
}
convert_alleles(my_allele_list)
my_allele_list
但是,正如您在第二遍中看到的那样,该函数不起作用 - 没有错误,只是没有对列表对象进行任何更改。我怀疑问题出在与 for 循环中的匿名函数发生冲突。有人可以解释问题所在并提出解决方案吗?
使用矢量化函数可能更容易,因为 str_replace
library(dplyr)
library(purrr)
library(stringr)
map(my_allele_list, ~ str_replace_all(.x, setNames(b, a)))
-输出
$loc1
[1] "A" "C"
$loc2
[1] "A" "G"
$loc3
[1] "T" "A"
$loc4
[1] "G" "G"
$loc5
[1] "A" "C"
$loc6
[1] "C" "T"
此外,如果它是固定匹配而不是示例中的部分匹配,请使用 setNames
创建命名向量并匹配并替换
map(my_allele_list, ~ unname(setNames(b, a)[.x]))
$loc1
[1] "A" "C"
$loc2
[1] "A" "G"
$loc3
[1] "T" "A"
$loc4
[1] "G" "G"
$loc5
[1] "A" "C"
$loc6
[1] "C" "T"
这也可以用 base R
-lapply
lapply(my_allele_list, \(x) unname(setNames(b, a)[x]))
$loc1
[1] "A" "C"
$loc2
[1] "A" "G"
$loc3
[1] "T" "A"
$loc4
[1] "G" "G"
$loc5
[1] "A" "C"
$loc6
[1] "C" "T"
在OP函数中,return
值应该是x
convert_alleles <- function(x){
a = c("001", "002", "003", "004")
b = c("A", "C", "G", "T")
for(i in seq_along(a)) x <-
lapply(x, function(x) gsub(a[i], b[i], x))
x
}
convert_alleles(my_allele_list)
$loc1
[1] "A" "C"
$loc2
[1] "A" "G"
$loc3
[1] "T" "A"
$loc4
[1] "G" "G"
$loc5
[1] "A" "C"
$loc6
[1] "C" "T"
注意:当我们运行函数时,它不会改变对象my_allele_list
。为此,我们分配回 (<-
)
my_allele_list <- convert_alleles(my_allele_list)