1

我想要做的是使用apply而不是循环来比较每行的两个字符串数组,例如x.str的第一行与y.str的第一行。

x.str

     [,1] [,2] [,3] [,4]
[1,] "c"  "o"  "m"  "e" 
[2,] "g"  "o"  "n"  "e" 
[3,] "b"  "o"  "o"  "d" 
[4,] "f"  "i"  "n"  "e" 

y.str

     [,1] [,2] [,3] [,4]
[1,] "t"  "o"  "o"  "t" 
[2,] "j"  "a"  "m"  "m" 
[3,] "b"  "e"  "e"  "n" 
[4,] "l"  "e"  "t"  "s" 

如果我要把它写成一个循环:

A = array(0,dim=dim(x.str1))
for(i in 1:length(x.str[,1])){
    A[i,] = ifelse(x.str[i,] %in% y.str[i,],1,0)
}

随着输出:

     [,1] [,2] [,3] [,4]
[1,]    0    1    1    0
[2,]    0    0    1    0
[3,]    1    0    0    0
[4,]    0    1    0    0

但是,实际数组的尺寸约为。

array(0,dim=c(10000,12)

因此,我想使用 apply 来比循环快得多。我已经查看了这个站点和其他站点,并尝试了许多不同的方法,但无法弄清楚如何选择正在处理的当前行,以在函数中使用。类似的帖子建议使用:

nrow()
rownames()

我像这样使用它们:

stringCom = function(x){
     i = nrow(x)
     ifelse(x.str[i,] %in% y.str1[i,],0,1)
}
apply(x.str,1,stringCom)

但我一直得到的只是错误。我努力了:

test = function(x){

  r = nrow(x)
  r
}
apply(x.str,1,test)

它只是给出 NULL 作为它的输出。rownames、NROW、names 等也会发生类似的情况。我确信可能有一个非常简单的答案,但似乎找不到它。

任何建议/帮助将不胜感激。

4

1 回答 1

0

如果你想一次迭代两件事,最好使用某种形式的mapply. 这是一些示例输入数据

x.str<-matrix(strsplit("cgbfoooimnoneede","")[[1]], ncol=4)
y.str<-matrix(strsplit("tjbloaeeomettmns","")[[1]], ncol=4)

那么你可以做类似的事情

t(mapply(function(a,b) a%in%b, 
    split(x.str, row(x.str)), split(y.str, row(y.str)))+0)

#   [,1] [,2] [,3] [,4]
# 1    0    1    0    0
# 2    0    0    0    0
# 3    1    0    0    0
# 4    0    0    0    1

它返回与您编写的代码相同的内容

A = array(0,dim=dim(x.str))
for(i in 1:length(x.str[,1])){
    A[i,] = ifelse(x.str[i,] %in% y.str[i,],1,0)
}
A
#      [,1] [,2] [,3] [,4]
# [1,]    0    1    0    0
# [2,]    0    0    0    0
# [3,]    1    0    0    0
# [4,]    0    0    0    1

但 for 循环并不总是很慢。您应该确保对不同的策略进行基准测试,以查看最适合任何给定应用程序的策略。最大的瓶颈是通常的内存管理。只要您为结果预定义所需的内存,for 循环通常会更快。

于 2015-02-03T00:31:38.283 回答