【问题标题】:How to use custom functions in mutate (dplyr)?如何在变异(dplyr)中使用自定义函数?
【发布时间】:2017-11-27 14:02:35
【问题描述】:

我正在使用 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 工作原理的误解。

【问题讨论】:

  • 我不同意您的函数适用于该表。
  • @RyanMorton 你是什么意思?
  • 它将始终使用这些值返回这些错误。另外,mutate() 是创建新变量,而sum()summarise() 函数。
  • @RyanMorton 在我的代码中唯一真正有效的函数是 mutate(sum = ref_SG1_E2_1_R1_Sum + alt_SG1_E2_1_R1_Sum)。所有其他人都没有,我正试图找出原因。

标签: r dplyr


【解决方案1】:

您的问题似乎是binom.test 而不是dplyrbinom.test 未矢量化,因此您不能指望它适用于矢量;你可以在mutate的两列上使用mapply

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(.)))

【讨论】:

  • 非常感谢!有用。您是否知道如何做同样的事情,但通过它们的索引引用这些列?
  • 你的意思是mapply(function(...), 2, 3)
  • 我试图让这段代码在未来更有用,所以列可以用不同的方式命名,最好有类似 mutate(p.val = mapply(function(x, y) binom.test.p(c(x,y)), select(.,2), select(.,3))) 但工作
  • 你可以尝试这样的事情,table %&gt;% mutate(Ratio = mapply(function(x, y) binom.test.p(c(x,y)), select(.,2)[[1]], select(.,3)[[1]]))。但不确定这可能有多动态。
【解决方案2】:

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

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!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多