【问题标题】:Combined mutate and function retuns error组合变异和函数返回错误
【发布时间】:2019-10-21 23:44:53
【问题描述】:

当我尝试遍历一个表执行一个使用bio3d 包的函数实现的操作时,我遇到了一个错误。我很确定问题不在于包裹。让我们看看。

首先,让我们准备好什么是有效的。


# load libraries
library(bio3d)
library(tidyverse)

# preparing files
ids <- c("1XVL_A", "4HMO_A", "4C0R_A", "4ONY_A", "4HN9_A", "4R6H_A", 
         "1UIV_A", "3RY3_A", "5BRA_A", "3EJW_A")
raw.files <- get.pdb(ids)
files <-pdbsplit(raw.files, ids)

to_ali <- tidyr::crossing( fixed=files, mobile=files)


to_ali
# A tibble: 100 x 2
   fixed                  mobile                
   <chr>                  <chr>                 
 1 split_chain/1UIV_A.pdb split_chain/1UIV_A.pdb
 2 split_chain/1UIV_A.pdb split_chain/1XVL_A.pdb
 3 split_chain/1UIV_A.pdb split_chain/3EJW_A.pdb
 4 split_chain/1UIV_A.pdb split_chain/3RY3_A.pdb
 5 split_chain/1UIV_A.pdb split_chain/4C0R_A.pdb
 6 split_chain/1UIV_A.pdb split_chain/4HMO_A.pdb
 7 split_chain/1UIV_A.pdb split_chain/4HN9_A.pdb
 8 split_chain/1UIV_A.pdb split_chain/4ONY_A.pdb
 9 split_chain/1UIV_A.pdb split_chain/4R6H_A.pdb
10 split_chain/1UIV_A.pdb split_chain/5BRA_A.pdb
# … with 90 more rows

现在,让我们定义我们的函数

my_rmsd <- function(fixed,mobile){
  print(class(fixed))
  a <- read.pdb(fixed)
  b <- read.pdb(mobile)
  r <- struct.aln(a, b)
  #paste("struct.aln(read.pdb(",fixed,"), read.pdb(",mobile,")")
  min(r$rmsd)
}

既然files是一个字符向量,我们看看这个函数是否有效

> my_rmsd(files[1],files[2])
[1] "character"
   PDB has ALT records, taking A only, rm.alt=TRUE

 Initial RMSD (267 atoms): 13.712
 Cycle 1: 11 atoms rejected
  Mean: 11.8 Std: 5.9 Cut: 23.5
  RMSD (256 of 267 atoms): 12.863
 Cycle 2: 12 atoms rejected
  Mean: 10.8 Std: 5.4 Cut: 21.7
  RMSD (244 of 267 atoms): 12.085
 Cycle 3: 13 atoms rejected
  Mean: 10.2 Std: 5 Cut: 20.2
  RMSD (231 of 267 atoms): 11.359
 Cycle 4: 9 atoms rejected
  Mean: 9.6 Std: 4.5 Cut: 18.7
  RMSD (222 of 267 atoms): 10.86
 Cycle 5: 11 atoms rejected
  Mean: 9.3 Std: 4.2 Cut: 17.7
  RMSD (211 of 267 atoms): 10.329
 Cycle 6: 6 atoms rejected
  Mean: 9 Std: 3.8 Cut: 16.6
  RMSD (205 of 267 atoms): 10.046
 Cycle 7: 6 atoms rejected
  Mean: 8.9 Std: 3.6 Cut: 16.1
  RMSD (199 of 267 atoms): 9.786
 Cycle 8: 5 atoms rejected
  Mean: 8.7 Std: 3.5 Cut: 15.6
  RMSD (194 of 267 atoms): 9.572
 Cycle 9: 3 atoms rejected
  Mean: 8.5 Std: 3.4 Cut: 15.2
  RMSD (191 of 267 atoms): 9.451
 Cycle 10: 2 atoms rejected
  Mean: 8.4 Std: 3.3 Cut: 15.1
  RMSD (189 of 267 atoms): 9.371
[1] 9.371

工作!

然后,让我们用它在我们的数据框中创建一个新列。

> to_ali %>%
  mutate(
    rmsd = my_rmsd(fixed, mobile)
  )

Error in .read_pdb(file, multi = multi, hex = hex, maxlines = maxlines,  : 
  Expecting a single string value: [type=character; extent=100].
In addition: Warning messages:
1: In if (substr(file, 1, 4) == "http") { :
  the condition has length > 1 and only the first element will be used
2: In if (toread & basename(file) != file) { :
  the condition has length > 1 and only the first element will be used
3: In if (!toread) { :
 Error in .read_pdb(file, multi = multi, hex = hex, maxlines = maxlines,  : 
  Expecting a single string value: [type=character; extent=100]. 
15.
stop(structure(list(message = "Expecting a single string value: [type=character; extent=100].", 
    call = .read_pdb(file, multi = multi, hex = hex, maxlines = maxlines, 
        atoms_only = ATOM.only), cppstack = NULL), class = c("Rcpp::not_compatible", 
"C++Error", "error", "condition"))) 
14.
.read_pdb(file, multi = multi, hex = hex, maxlines = maxlines, 
    atoms_only = ATOM.only) 
13.
read.pdb(fixed) 
12.
my_rmsd(fixed, mobile) 
11.
mutate_impl(.data, dots, caller_env()) 
10.
mutate.tbl_df(., rmsd = my_rmsd(fixed, mobile)) 
9.
mutate(., rmsd = my_rmsd(fixed, mobile)) 
8.
function_list[[k]](value) 
7.
withVisible(function_list[[k]](value)) 
6.
freduce(value, `_function_list`) 
5.
`_fseq`(`_lhs`) 
4.
eval(quote(`_fseq`(`_lhs`)), env, env) 
3.
eval(quote(`_fseq`(`_lhs`)), env, env) 
2.
withVisible(eval(quote(`_fseq`(`_lhs`)), env, env)) 
1.
to_ali %>% mutate(rmsd = my_rmsd(fixed, mobile)) 

没有用。为什么?

我不明白这个错误。 有谁知道可能发生了什么?或者可以建议另一种策略,而不是使用dplyr::mutate

我想要的是一个像to_ali 这样的数据框,但第三列的结果是rmsdfixedmobile 列之间。

实际上,我以一种奇怪的方式做到了:

sapply(files[1:3], function(x) sapply(files[1:3], function(y) my_rmsd(x,y))) %>%
  cbind(fixed=rownames(.)) %>%
  as_tibble() %>%
  gather(key=mobile, value = "rmsd", -fixed)

但感谢任何帮助或改进。
另外,如果可能的话,很高兴了解为什么我不能使用dplyr::mutate 执行此操作。

我想并行执行每条线以加快操作速度。我不知道如何使用上面的sapply 方法来做到这一点。至少,对于mutate,有一些替代方案可以使其瘫痪。

提前致谢

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    我通过使用dplyr::group_by 解决了使用dplyr::mutate 的问题。

    to_ali %>%
      group_by(fixed, mobile) %>%
      mutate(
        rmsd = my_rmsd(fixed,mobile)
      )
    

    变异件将向量作为参数传递而不是在[line, column] 中传递基于单个值的接缝。 dplyr::group_by 在这种情况下使其每个向量由单个值组成。

    此解决方案使遍历数据框变得容易。但仍然缺少并行化,我认为使用 group_by 不是更好的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-28
      • 2015-09-30
      • 2018-07-26
      • 2020-05-09
      相关资源
      最近更新 更多