【问题标题】:How to use apply instead of for loop for stringMatch function?stringMatch 函数如何使用 apply 而不是 for 循环?
【发布时间】:2012-06-19 18:28:28
【问题描述】:

我正在尝试计算一长串序列之间的成对差异的数量,并将其放回矩阵形式。这是我想做的一个玩具示例。

library(MiscPsycho)
b <- c("-BC", "ACB", "---") # Toy example of sequences
workb <- expand.grid(b,b)
new <- c(1:9)

# Need to get rid of this for loop somehow
for (i in 1:9) {
new[i] <- stringMatch(workb[i,1], workb[i,2], normalize="NO")
}

workb <- cbind(workb, new)
newmat <- reShape(workb$new, id=workb$Var1, colvar=workb$Var2)

a <- c("Subject1", "Subject2", "Subject3") #Relating it back to the subject ID
colnames(newmat) <- a
rownames(newmat) <- a
newmat

我对使用 apply 函数不是很熟悉,但我想用它来替换 for 循环,考虑到我有大量序列,它可能会变慢。 (stringMatch 函数来自 MiscPsycho)。请告诉我如何提高效率!

非常感谢!

【问题讨论】:

  • 有什么方法可以让代码更高效吗?下面的不同解决方案适用于短序列,但我有几百个序列,我正在尝试为它们构建一个成对差分矩阵,并且每个序列都具有相同的长度(大约 300 个字符)。当我使用下面的代码时,只需半个多小时就可以制作一个比较 20 个序列的矩阵...

标签: r for-loop string-matching apply


【解决方案1】:

为了获得那些“成对距离”,我会做这样的事情:

  Vm <- Vectorize(stringMatch)
  nex <- outer(b,b, FUN=Vm, normalize = "NO")
 nex
     [,1] [,2] [,3]
[1,]    0    3    2
[2,]    3    0    3
[3,]    2    3    0

【讨论】:

  • 只有收到这样的消息才会想到:Error in outer(b, b, FUN = stringMatch) : dims [product 9] do not match the length of object [1]
  • 非常感谢!!效果很好,而且比我以前的效率高得多。
【解决方案2】:

替换循环

new <- apply(workb, 1, function(x) stringMatch(x[[1]],x[[2]], normalize="NO"))

【讨论】:

  • 太好了,谢谢!!那是我希望写的,但我只是对语法感到困惑。
【解决方案3】:

我会创建一个函数来获取您的索引i,并返回new[i]

myfun <- function(i) {
  stringMatch(workb[i, 1], workb[i, 2], normalize='NO')
}

然后你可以apply沿着你的新向量:

workb$new <- unlist(lapply(new, myfun))

一般来说,您在 R 中正确使用了 for loop。您已经预先分配了向量 new,并且正在填充它而不是增长它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-08
    • 2023-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多