如何在mutate(dplyr)中使用自定义函数?

kin*_*any 8 r dplyr mutate

我正在使用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)
  }
} 
Run Code Online (Sandbox Code Playgroud)

我的数据:

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))
Run Code Online (Sandbox Code Playgroud)

所以我这样做:

table %>%
  mutate(Ratio=binom.test.p(c(ref_SG1_E2_1_R1_Sum, alt_SG1_E2_1_R1_Sum)))
Error: incorrect length of 'x'
Run Code Online (Sandbox Code Playgroud)

如果我做:

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))
Run Code Online (Sandbox Code Playgroud)

第二个错误可能是因为我的函数需要一个向量而是获得两个参数.

但即使忘记了我的功能.这有效:

table %>%
  mutate(sum = ref_SG1_E2_1_R1_Sum + alt_SG1_E2_1_R1_Sum)
Run Code Online (Sandbox Code Playgroud)

这不是:

    table %>%
      mutate(.cols=c(2:3), .funs=funs(sum=sum(.)))
Error: wrong result size (2), expected 4 or 1
Run Code Online (Sandbox Code Playgroud)

所以这可能是我对dplyr如何工作的误解.

Mar*_*tin 11

在许多情况下,创建函数的矢量化版本就足够了:

your_function_V <- Vectorize(your_function)
Run Code Online (Sandbox Code Playgroud)

然后,矢量化函数可在 dplyr 的mutate. 另请参阅这篇博文

然而,问题中发布的函数从两个不同的列获取一个二维输入。因此,我们需要对其进行修改,以便在矢量化之前输入是单独的。

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!
Run Code Online (Sandbox Code Playgroud)


Psi*_*dom 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
Run Code Online (Sandbox Code Playgroud)

至于最后一个,你需要mutate_at代替mutate:

table %>%
      mutate_at(.vars=c(2:3), .funs=funs(sum=sum(.)))
Run Code Online (Sandbox Code Playgroud)