我正在使用dplyr重写我的所有代码,并需要mutate / mutate_at函数的帮助。我需要的是将自定义函数应用于我的表中的两列。理想情况下,我会通过它们的索引来引用这些列,但现在我甚至无法通过名称引用它。
功能是:
binom.test.p <- function(x) {
if (is.na(x[1])|is.na(x[2])|(x[1]+x[2])<10) {
return(NA)
}
else {
return(binom.test(x, alternative="two.sided")$p.value)
}
}
我的数据:
table <- data.frame(geneId=c("a", "b", "c", "d"), ref_SG1_E2_1_R1_Sum = c(10,20,10,15), alt_SG1_E2_1_R1_Sum = c(10,20,10,15))
所以我这样做:
table %>%
mutate(Ratio=binom.test.p(c(ref_SG1_E2_1_R1_Sum, alt_SG1_E2_1_R1_Sum)))
Error: incorrect length of 'x'
如果我这样做:
table %>%
mutate(Ratio=binom.test.p(ref_SG1_E2_1_R1_Sum, alt_SG1_E2_1_R1_Sum))
Error: unused argument (c(10, 20, 10, 15))
第二个错误可能是因为我的函数需要一个向量而是获取两个参数。
但即使忘了我的功能。这有效:
table %>%
mutate(sum = ref_SG1_E2_1_R1_Sum + alt_SG1_E2_1_R1_Sum)
这不是:
table %>%
mutate(.cols=c(2:3), .funs=funs(sum=sum(.)))
Error: wrong result size (2), expected 4 or 1
所以这可能是我对dplyr如何运作的误解。
答案 0 :(得分:6)
您的问题似乎是binom.test
而不是dplyr
,binom.test
没有矢量化,因此您不能指望它适用于矢量;您可以在mapply
的两列上使用mutate
:
table %>%
mutate(Ratio = mapply(function(x, y) binom.test.p(c(x,y)),
ref_SG1_E2_1_R1_Sum,
alt_SG1_E2_1_R1_Sum))
# geneId ref_SG1_E2_1_R1_Sum alt_SG1_E2_1_R1_Sum Ratio
#1 a 10 10 1
#2 b 20 20 1
#3 c 10 10 1
#4 d 15 15 1
至于最后一个,您需要mutate_at
而不是mutate
:
table %>%
mutate_at(.vars=c(2:3), .funs=funs(sum=sum(.)))
答案 1 :(得分:1)
在许多情况下,创建函数的矢量化版本就足够了:
your_function_V <- Vectorize(your_function)
然后,矢量化函数可在dplyr的mutate
中使用。另请参见this blog post。
问题中发布的函数但是从两个不同的列中获取一个二维输入。因此,在矢量化之前,我们需要对此进行修改,以使输入是单独的。
binom.test.p <- function(x, y) {
# input x and y
x <- c(x, y)
if (is.na(x[1])|is.na(x[2])|(x[1]+x[2])<10) {
return(NA)
}
else {
return(binom.test(x, alternative="two.sided")$p.value)
}
}
# vectorized function
binom.test.p_V <- Vectorize(binom.test.p)
table %>%
mutate(Ratio = binom.test.p_V(ref_SG1_E2_1_R1_Sum, alt_SG1_E2_1_R1_Sum))
# works!