【问题标题】:Remove common characters in lists of lists删除列表列表中的常用字符
【发布时间】:2022-01-02 07:47:18
【问题描述】:

我有一个列表列表(包含字符),我想删除这些子列表之间的公共字符。

例如

mylist = list(
list("tata","titi","toto","tete"),
list("fifi","fafa","toto","fefe"),
list("fifi","toto","rere","rara")
)

变成

mylist = list(
list("tata","titi","tete"),
list("fafa","fefe"),
list("rere","rara")
)

我首先创建了一个公共元素列表,并尝试从子列表中继承这个列表,但它不起作用

common_elements = list(Reduce(intersect, mylist))
mylist = mylist[!(mylist %in% common_elements)]

你能帮我吗?谢谢!

【问题讨论】:

    标签: r list


    【解决方案1】:

    我们可以使用与上一篇文章类似的解决方案,通过在enframe 之后将嵌套列表两次unnesting 到两列标题。按'value'分组后,filter'name'中不同元素个数为1的行,然后splitlist通过'name'转换(as.list)'value'列

    library(dplyr)
    library(tibble)
    library(tidyr)
    mylist2 <- enframe(mylist) %>%
        unnest(value)  %>%  
        unnest(value) %>%
        group_by(value) %>%
        filter(n_distinct(name) == 1) %>% 
        with(., split(as.list(value), name)) %>%
        unname
    

    -输出

    > str(mylist2)
    List of 3
     $ :List of 3
      ..$ : chr "tata"
      ..$ : chr "titi"
      ..$ : chr "tete"
     $ :List of 2
      ..$ : chr "fafa"
      ..$ : chr "fefe"
     $ :List of 2
      ..$ : chr "rere"
      ..$ : chr "rara"
    

    【讨论】:

      【解决方案2】:

      对于这种情况,列表的元素最好是原子向量,而不是列表本身。比如这样:

      mylist <- list(
          c("tata","titi","toto","tete"),
          c("fifi","fafa","toto","fefe"),
          c("fifi","toto","rere","rara")
      )
      

      您可以通过说mylist_atomic &lt;- lapply(mylist, unlist) 之类的话将您的原始格式转换为这种格式。

      如果我正确理解您的问题,您希望将列表中的每个元素过滤为仅未出现在 >1 列表元素中的字符串。

      如果您不关心效率,这是实现此目的的一种直接方法:

      appears_in <- function(mylist, string){
          # check how many elements of `mylist` the arg `string` appears in 
          return(sum(sapply(mylist, function(v) string %in% v)))
      }
      
      filter_list <- function(mylist){
          result <- vector(mode='list', length=3)
          for (idx in seq_along(mylist)){
              elem <- mylist[[idx]]
              for (string in elem){
                  if (appears_in(mylist, string) == 1){
                      result[[idx]] <- c(result[[idx]], string)
                  }
              }
          }
          return(result)
      }
      

      然后你可以像这样调用filter_list():

      mylist_original <- list(
          c("tata","titi","toto","tete"),
          c("fifi","fafa","toto","fefe"),
          c("fifi","toto","rere","rara")
      )
      
      mylist_filtered <- filter_list(mylist_original)
      
      print(mylist_filtered)
      # [[1]]
      # [1] "tata" "titi" "tete"
      # 
      # [[2]]
      # [1] "fafa" "fefe"
      # 
      # [[3]]
      # [1] "rere" "rara"
      

      给猫剥皮的方法有很多种,这就是其中之一。

      【讨论】:

        【解决方案3】:

        从你所在的地方继续:

         mylist2 <- lapply(mylist,\(x)x[!x%in% unlist(common_elements)])
        

         dput(mylist2)
        
         list(
              list("tata", "titi", "tete"), 
              list("fifi", "fafa", "fefe"), 
              list("fifi", "rere", "rara")
         )
        

        这正是你要找的东西

        【讨论】:

          猜你喜欢
          • 2015-10-25
          • 1970-01-01
          • 2012-04-18
          • 1970-01-01
          • 2022-01-08
          • 1970-01-01
          • 2011-11-01
          • 1970-01-01
          • 2022-01-02
          相关资源
          最近更新 更多