【问题标题】:Applying unique() to each element in list将 unique() 应用于列表中的每个元素
【发布时间】:2017-06-19 11:48:58
【问题描述】:

我有一个包含几个不同长度元素的列表。

mylist <- list(one=c("A","B","B"), two=c("A","A","B"), three=c("X","X","Y"))

我想选择具有一组特定唯一值的元素,比如元素onetwo,它们都有唯一值"A","B"

我试过了

cond <- sapply(mylist, function(x) unique(x)==c("A","B"))
mylist[cond]

但这似乎不起作用。

【问题讨论】:

  • 如果您查看cond,您会发现有些事情发生了。然后看看unique(c("A","A","B")) == c("A","B") - 两个 TRUE 的值。 R 比较每个元素并为每个元素返回真/假。

标签: r list unique


【解决方案1】:

我希望我正确理解了您的需求。如果是这样,这将是:

mylist2 <- lapply(mylist,function(x) x[all(c("A","B") %in% unique(x))])

mylist2 <- lapply(mylist,function(x) x[all(c("A","B") == unique(x))])

这些本质上是相同的,如果您删除 all 函数,您还可以返回值的子集。

如果您不喜欢索引,也可以使用简单的if 条件(或ifelse):

lapply(mylist,function(x) if(all(c("A","B") == unique(x))) x)

mylist2 <- lapply(mylist,function(x) if(all(c("A","B") %in% unique(x))) x)

编辑:

根据您的最后评论,我认为这种强大的解决方案最适合您的数据可能发生的变化:

mylist <- list(one=c("A","B","B"), two=c("A","A","B"), three=c("X","X","Y"),four=c("A","B","X"))

mylist2 <- lapply(mylist,function(x) if(all(unique(x) %in% c("A","B")) & all(c("A","B") %in% unique(x))) x)

我放弃了== 版本,因为它们无法处理不同数量的元素进行比较。我还在if 语句中添加了第二个条件。现在它将丢弃唯一值包含其他附加元素而不是您要查找的元素的情况。

【讨论】:

  • 第一个也适用于更复杂的设置,但第二个列出了仅满足部分条件的元素 - 尝试例如将元素 four=c("A","X","X") 添加到列表中。有没有办法让它不显示不符合条件的元素?
  • 好的,现在明白了,谢谢。但是,对于所有方法,mylist2 的长度都与mylist 相同,其中一些元素等于NULLcharacter(0)。索引会很棒,但我看不到。
  • 如果没有找到您的组合,mylist2 中的相应条目将不会返回任何值。但是该条目仍然存在(但为空),因此相同的length。根据您的实际问题是什么样的以及您的最终目标是什么,这些空元素将在接下来的步骤中被删除,或者可以使用mylist2[lapply(mylist2,length)&gt;0] 之类的小函数轻松过滤。至于索引,我的意思是返回正在发生的值。这是你需要的吗?
  • 知道了!很近。我刚刚注意到它还包括具有声明的唯一值和更多的元素——例如four=c("A","B","X")。有没有办法将元素限制为仅声明唯一值的元素?
  • 我编辑了我的解决方案。请注意,对于更新后的问题,以前的解决方案无法正常工作。所以请只参考最新的代码。
【解决方案2】:

另一个想法是使用setdiff

Filter(length, lapply(mylist, function(i) i[length(setdiff(unique(i), c('A', 'B'))) == 0]))
#$one
#[1] "A" "B" "B"

#$two
#[1] "A" "A" "B"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-24
    • 1970-01-01
    • 2014-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多