【问题标题】:Test arrays of paired words to find out which letters the pairs share测试成对单词的数组以找出这些对共享哪些字母
【发布时间】:2015-02-02 23:59:00
【问题描述】:

我想要做的是使用 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 而不是比循环快得多。我已经查看了这个站点和其他站点,并尝试了许多不同的方法,但无法弄清楚如何选择正在处理的当前行 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 等也会发生类似的情况。我确信可能有一个非常简单的答案,但似乎找不到。

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

【问题讨论】:

  • 你想要的输出对我来说毫无意义。我完全不知道正在检查什么。
  • 我想比较成对单词的列表,以找出这些对相互共享的字母,计算出它们共享的总数、它们共享的唯一字母总数以及共享的位置字母。我能想到的唯一方法是使用 %in% 并执行两次 a%in%b 和 b%in%a 而不编写多个循环来逐个字母地测试。我已经意识到上面的输出是错误的,因为那是 y.str %in% x.str 的输出(对此感到抱歉)。希望这会有所帮助,感谢您抽出宝贵时间回复。
  • 好了,x.str/y.str的每一行代表一个单词的组成字母。您想测试 y.str 行中的每个单独 letter 是否在 x.str 的相应行中。
  • 是的,这正是我想做的

标签: r apply rowname


【解决方案1】:

如果你想一次迭代两个东西,最好使用某种形式的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 循环通常会更快。

【讨论】:

  • 感谢您对这个相当新的编程和不流利的编程演讲,所以很难理解类似功能(如 apply mapply 等)之间的技术差异。所以快速的问题是“预定义所需的内存”在实现使用它们的循环、函数等之前,确保我在可能的情况下在脚本开头预定义数组大小(例如 A = array(0,dim=dim(x.str)))?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-28
  • 1970-01-01
  • 1970-01-01
  • 2011-07-03
  • 2023-03-22
相关资源
最近更新 更多