【问题标题】:How Can I compare the subvalues in a list to eachother using a for-loop?如何使用 for 循环将列表中的子值相互比较?
【发布时间】:2019-06-17 05:50:31
【问题描述】:

目前我有一个如下所示的列表。我想开发一个 forloop 遍历列表中的每个项目并比较该列表中的字符。一个项目中的字符永远不会超过两个。

all = [[a,z]],[[a,a]],[[e,r]],[[p,p]]....(更多类似项目)]

也写成:

[[1]]
[1] "a" "z"

[[2]]
[1] "a" "a"

[[3]] 
[1] "e" "r"

[[4]] 
[1] "p" p"

我想遍历列表中的每个元素并测试项目是否相同。我想打印匹配的项目数。例如,在这个列表中,我想要:

[[2]]
 [1] "a" "a"

 [[4]] 
 [1] "p" p"

因为“a”匹配“a”,“p”匹配“p”。我希望 for 循环返回值 2,计算匹配数。

有什么建议吗?

【问题讨论】:

  • 还有一个:sum(sapply(lst, duplicated))
  • 感谢我将它添加到我的基准测试中

标签: r list for-loop


【解决方案1】:

sapplyuniqueN 一起使用

lst1[sapply(lst1,data.table::uniqueN)==1]
[[1]]
[1] "a" "a"

[[2]]
[1] "p" "p"

【讨论】:

  • 欢迎回到 R 端,Python Pandas 大师!
  • @Parfait 谢谢伙计,我会尽力提高我的 R 技能 :-)
  • 它也适用于 dplyr::n_distinct 而不是 data.table::uniqueN,并且在我的计算机上使用 dplyr 时速度快两倍。
  • @Moody_Mudskipper 太棒了,谢谢你的信息:-)
【解决方案2】:

我们可以使用Filter 来过滤list 的元素,方法是创建一个逻辑条件,将每个list 元素中的lengthunique 元素检查为1

out <- Filter(function(x) length(unique(x))==1, lst1)
out
#[[1]]
#[1] "a" "a"

#[[2]]
#[1] "p" "p"

length(out)
#[1] 2

或者另一种选择是

sum(sapply(lst1, function(x) do.call(identical, as.list(x))))

数据

lst1 <- list(c('a', 'z'), c('a', 'a'), c('e', 'r'), c('p', 'p'))

【讨论】:

    【解决方案3】:

    这里还有 3 种方法:

    sum((x<-unlist(lst1))[c(T,F)]==x[c(F,T)])
    #[1] 2
    sum(sapply(lst1,function(x) x[1] == x[2]))
    #[1] 2
    sum(lengths(sapply(lst1,unique))==1)
    #[1] 2
    

    还有一个基准:

    lst2 <- rep(lst1,1000)
    
    microbenchmark::microbenchmark(
      mm1 = sum((x<-unlist(lst2))[c(T,F)]==x[c(F,T)]),
      mm2 = sum(sapply(lst2,function(x) x[1] == x[2])),
      mm3 = sum(lengths(sapply(lst2,unique))==1),
      akrun = length(Filter(function(x) length(unique(x))==1, lst2)),
      WB  = length(lst2[sapply(lst2,data.table::uniqueN)==1]),
      WB2 = length(lst2[sapply(lst2,dplyr::n_distinct)==1]),
      dd  = sum(sapply(lst2, duplicated)),
      dd2 = sum(sapply(lst2, function(x) duplicated(x)[2]))
    )
    
    # Unit: microseconds
    #  expr       min        lq      mean    median        uq        max neval    cld
    # mm1     146.104   156.972   284.218   160.292   164.368   9357.887   100 a     
    # mm2    4141.922  4493.899  5211.921  5043.449  5550.736   8576.352   100  b    
    # mm3   15911.727 17504.531 19123.916 19108.955 20324.424  26267.587   100    de 
    # akrun 17991.895 19451.122 21222.071 20960.609 22765.172  29885.165   100     e 
    # WB    31602.789 36288.222 39258.331 37895.967 39659.628 134526.556   100      f
    # WB2   14003.624 15026.653 16783.403 15391.911 16116.695 119739.284   100   c   
    # dd    14493.253 15950.668 17077.778 16792.124 17932.125  21876.323   100   cd  
    # dd2   16532.970 17768.060 19172.640 18722.867 20769.075  24318.128   100    de 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-04
      • 2021-10-22
      • 1970-01-01
      • 2013-07-18
      相关资源
      最近更新 更多