首页 > 解决方案 > R错误:“哪个”的参数不合逻辑

问题描述

我有一个带有文件名的向量。向量中的几个文件以不同的版本重复。例如

“ConsoleKit2-1.0.0-x86_64-3”

“ConsoleKit2-1.0.0-x86_64-4”

“赛通-0.23.4-x86_64-1”

“Cython-0.29.12-x86_64-1”

“GConf-3.2.6-x86_64-3”

“GConf-3.2.6-x86_64-4”

“LibRaw-0.17.2-x86_64-1”

“LibRaw-0.18.12-x86_64-1”

“M2Crypto-0.23.0-x86_64-1”

“M2Crypto-0.35.2-x86_64-1”

“MPlayer-1.2_20160125-x86_64-3”

“MPlayer-20190418-x86_64-1”

“Mako-1.0.13-x86_64-1”

“ModemManager-1.10.4-x86_64-1”

“ModemManager-1.4.14-x86_64-1”

“网络管理器-1.18.1-x86_64-1”

“网络管理器-1.2.2-x86_64-2”

“PyQt-4.11.4-x86_64-1”

“PyQt-4.12.1-x86_64-3”

“QScintilla-2.10.8-x86_64-2”

dput(hd1)
c("ConsoleKit2-1.0.0-x86_64-3", "ConsoleKit2-1.0.0-x86_64-4", 
"Cython-0.23.4-x86_64-1", "Cython-0.29.12-x86_64-1", "GConf-3.2.6-x86_64-3", 
"GConf-3.2.6-x86_64-4", "LibRaw-0.17.2-x86_64-1",   "LibRaw-0.18.12-x86_64-1", 
"M2Crypto-0.23.0-x86_64-1", "M2Crypto-0.35.2-x86_64-1", "MPlayer-1.2_20160125-x86_64-3", 
"MPlayer-20190418-x86_64-1", "Mako-1.0.13-x86_64-1", "ModemManager-1.10.4-x86_64-1", 
"ModemManager-1.4.14-x86_64-1", "NetworkManager-1.18.1-x86_64-1", 
"NetworkManager-1.2.2-x86_64-2", "PyQt-4.11.4-x86_64-1",    "PyQt-4.12.1-x86_64-3", 
"QScintilla-2.10.8-x86_64-2")

我想制作一个新的向量,它只包含与多个版本一起出现的每个文件的最新版本。例如,新列表将以

“ConsoleKit2-1.0.0-x86_64-4”

“Cython-0.29.12-x86_64-1” ...

我列出了具有多个版本的文件,以便我可以将它们与所有文件的列表进行比较。

dput(fix1[1:30])
c("ConsoleKit2", "Cython", "GConf", "LibRaw", "M2Crypto", "MPlayer", 
"ModemManager", "NetworkManager", "PyQt", "QScintilla", "Thunar", 
"a2ps", "a52dec", "aaa_base", "aaa_elflibs", "aaa_terminfo", 
"aalib", "acct", "acl", "acpid", "adwaita-icon-theme", "akonadi", 
"alpine", "alsa-lib", "alsa-oss", "alsa-plugins", "alsa-utils", 
"amarok", "amor", "amp")

我写了一个小函数来比较完整列表和具有多个版本的文件列表,但我不断收到一个我不明白的错误。

该功能有几个步骤,我在这里简化了功能,因为错误发生得早。

> ser2 <- function(in1, ... ) {
+ out1 = NULL  #output
+ l1 <- hd1 #list of all files
+ for (i in 1:length(in1 )) {
+ out1[i] = l1[which(grepl(in1[i], l1))][1]  #start to filter the main list by list of dupes
+ }
+ return(out1)
+ }
> 
> 
> ser2(fix1)
Error in which(grepl(in1[i], l1)) : argument to 'which' is not logical
> traceback()
2: which(grepl(in1[i], l1)) at #5
1: ser2(fix1)

我不知道为什么which(grepl(in1[i], l1))在函数内部返回此错误。如果我使用

> which(grepl(fix1[2], hd1)) [1] 3 4

它工作正常。

 sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-slackware-linux-gnu (64-bit)
Running under: Slackware 14.2 x86_64 (post 14.2 -current)

Matrix products: default
BLAS:   /usr/lib64/R/lib/libRblas.so
LAPACK: /usr/lib64/R/lib/libRlapack.so

locale:
 [1] LC_CTYPE=en_US       LC_NUMERIC=C         LC_TIME=en_US       
 [4] LC_COLLATE=C         LC_MONETARY=en_US    LC_MESSAGES=en_US   
 [7] LC_PAPER=en_US       LC_NAME=C            LC_ADDRESS=C        
[10] LC_TELEPHONE=C       LC_MEASUREMENT=en_US LC_IDENTIFICATION=C 

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] stringr_1.4.0

loaded via a namespace (and not attached):
[1] compiler_3.6.1 magrittr_1.5   tools_3.6.1    stringi_1.4.3 

编辑-我在 nograpes 的回答之后稍微更改了示例函数。which()关于不合逻辑的论点,我仍然得到同样的错误。

标签: r

解决方案


你的代码对我来说不会以同样的方式失败。如果我运行:

hd1 <- c("ConsoleKit2-1.0.0-x86_64-3", "ConsoleKit2-1.0.0-x86_64-4", 
     "Cython-0.23.4-x86_64-1", "Cython-0.29.12-x86_64-1", "GConf-3.2.6-x86_64-3", 
     "GConf-3.2.6-x86_64-4", "LibRaw-0.17.2-x86_64-1",   "LibRaw-0.18.12-x86_64-1", 
     "M2Crypto-0.23.0-x86_64-1", "M2Crypto-0.35.2-x86_64-1", "MPlayer-1.2_20160125-x86_64-3", 
     "MPlayer-20190418-x86_64-1", "Mako-1.0.13-x86_64-1", "ModemManager-1.10.4-x86_64-1", 
     "ModemManager-1.4.14-x86_64-1", "NetworkManager-1.18.1-x86_64-1", 
     "NetworkManager-1.2.2-x86_64-2", "PyQt-4.11.4-x86_64-1",    "PyQt-4.12.1-x86_64-3", 
     "QScintilla-2.10.8-x86_64-2")

fix1 <- c("ConsoleKit2", "Cython", "GConf", "LibRaw", "M2Crypto", "MPlayer", 
      "ModemManager", "NetworkManager", "PyQt", "QScintilla", "Thunar", 
      "a2ps", "a52dec", "aaa_base", "aaa_elflibs", "aaa_terminfo", 
      "aalib", "acct", "acl", "acpid", "adwaita-icon-theme", "akonadi", 
      "alpine", "alsa-lib", "alsa-oss", "alsa-plugins", "alsa-utils", 
      "amarok", "amor", "amp")

ser2 <- function(in1, ... ) {
  out1 = NULL  #output
  l1 <- hd1 #list of all files
  for (i in 1:length(in1 )) {
    dec1 = l1[which(grepl(in1[i], l1))][1]  #start to filter the main list by list of dupes
    dec2 = l1[which(grepl(in1[i], l1))][2]
  }
  return(list(dec1, dec2))
}

ser2(fix1)

我明白了list(NA, NA)。那是因为您不断覆盖相同的dec1,并且dec2对于in1. 因此,返回值只为您提供匹配amp项,而hd1.

我认为您在此功能中尝试完成的工作最好通过以下方式完成:

lapply(fix1, grep, hd1, value = TRUE)

这样做是grep(fix1[i], hd1, value = TRUE)针对 的所有i值运行fix1,并将它们粘贴在一个列表中。

假设hd1按最早到最新的顺序排序,您可以使用tail.

matches <- lapply(fix1, grep, hd1, value = TRUE)
unlist(lapply(matches, tail, 1))
# [1] "ConsoleKit2-1.0.0-x86_64-4"    "Cython-0.29.12-x86_64-1"      
# [3] "GConf-3.2.6-x86_64-4"          "LibRaw-0.18.12-x86_64-1"      
# [5] "M2Crypto-0.35.2-x86_64-1"      "MPlayer-20190418-x86_64-1"    
# [7] "ModemManager-1.4.14-x86_64-1"  "NetworkManager-1.2.2-x86_64-2"
# [9] "PyQt-4.12.1-x86_64-3"          "QScintilla-2.10.8-x86_64-2"

推荐阅读