如何使用 for 循环将列表中的子值相互比较?
Posted
技术标签:
【中文标题】如何使用 for 循环将列表中的子值相互比较?【英文标题】:How Can I compare the subvalues in a list to eachother using a for-loop? 【发布时间】: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))
感谢我将它添加到我的基准测试中
【参考方案1】:
将sapply
与uniqueN
一起使用
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
元素中的length
和unique
元素检查为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
【讨论】:
以上是关于如何使用 for 循环将列表中的子值相互比较?的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 for 循环的情况下将列表中的所有项目与整数进行比较