【问题标题】:Append two consecutive item in list [duplicate]在列表中追加两个连续项目[重复]
【发布时间】:2020-10-29 11:16:39
【问题描述】:

如何使用另一个列表长度在 R 列表中附加两个连续的项目?

a <- list( "a", "b", "c")
audit <- list()
j <- 0
for (i in 1:length(a)){
 pre <- paste(a[i], "_present")
 nonpre <- paste(a[i], "_non_present")
 i <- j+1
 audit[[i]]<- pre
 j <- i+1
 audit[[j]] <- nonpre
}

Result:audit["a_present, "a_non_present", "b_present", "b_non_present", "c_present", "c_non_present"]

我的解决方案很脏。任何更聪明的方式都值得赞赏。追加到列表的其他方法是什么?

【问题讨论】:

    标签: r list append


    【解决方案1】:

    您可以使用outer

    outer(a, c('_present', '_non_present'), paste0)
    
    #           [,1]        [,2]           
    #[1,] "a_present" "a_non_present"
    #[2,] "b_present" "b_non_present"
    #[3,] "c_present" "c_non_present"
    

    如果你想以列表形式输出:

    as.list(t(outer(a, c('_present', '_non_present'), paste0)))
    
    
    #[[1]]
    #[1] "a_present"
    
    #[[2]]
    #[1] "a_non_present"
    
    #[[3]]
    #[1] "b_present"
    
    #[[4]]
    #[1] "b_non_present"
    
    #[[5]]
    #[1] "c_present"
    
    #[[6]]
    #[1] "c_non_present"
    

    【讨论】:

      【解决方案2】:

      您可以使用 purrr::map 从 a 创建一个元素的元组,并与 _present' &amp; '_not_present', then just unlist` 连接得到一个向量的结果:)

      library(purrr)
      
      a <- list("a", "b", "c")
      unlist(purrr::map(a, function(i){paste0(i, c('_present','_not_present'))}))
      

      这会在向量中为您提供所需的输出:

      [1] "a_present"     "a_not_present" "b_present"     "b_not_present" "c_present"     "c_not_present"
      

      【讨论】:

        【解决方案3】:

        您可以使用sapply。这里我使用了paste0 而不是paste

        as.list(sapply(a, function(i) paste0(i, c('_present','_non_present'))))
        
        [[1]]
        [1] "a_present"
        
        [[2]]
        [1] "a_non_present"
        
        [[3]]
        [1] "b_present"
        
        [[4]]
        [1] "b_non_present"
        
        [[5]]
        [1] "c_present"
        
        [[6]]
        [1] "c_non_present"
        

        【讨论】:

          【解决方案4】:

          你可以使用sapplyReduce来获得一个简单的向量:

          Reduce(`c`, sapply(a, function(x) paste0(x, c('_present','_not_present'))))
          

          输出

          [1] "a_present"     "a_not_present" "b_present"     "b_not_present" "c_present"     "c_not_present
          

          更新

          在意识到我的解决方案可能非常慢之后,我又添加了两个函数并进行了基准测试:

          fun1 <- function(y) Reduce(`c`, sapply(y, function(x) paste0(x, c('_prfun1 <- function(y) Reduce(`c`, sapply(y, function(x) paste0(x, c('_present','_not_present'))))
          fun2 <- function(y) unlist(purrr::map(y, function(i){paste0(i, c('_present','_not_present'))}))
          fun3 <- function(y) as.list(sapply(y, function(i) paste0(i, c('_present','_non_present'))))
          fun4 <- function(y) array(sapply(y, function(x) paste0(x, c('_present','_not_present'))))
          fun5 <- function(y) as.vector(sapply(y, function(x) paste0(x, c('_present','_not_present'))))
          
          fun6 <- function(y){
          audit <- list()
          j <- 0
          for (i in 1:length(y)){
            pre <- paste(y[i], "_present")
            nonpre <- paste(y[i], "_non_present")
            i <- j+1
            audit[[i]]<- pre
            j <- i+1
            audit[[j]] <- nonpre
          }
          audit
          }
          
          
          x <- list(sample(letters, 1000, replace = TRUE))
          microbenchmark::microbenchmark(fun1(x), fun2(x), fun3(x), fun4(x), fun5(x), fun6(x), times = 10L)
          

          结果

              Unit: microseconds
              expr      min       lq      mean    median       uq      max neval
           fun1(x) 2886.633 3107.855 3673.7590 3191.4295 3965.469 6969.991    10
           fun2(x)  225.562  235.774  553.8192  277.9055  407.876 2839.410    10
           fun3(x)  237.601  245.103  643.7252  261.1835  407.830 3840.739    10
           fun4(x)  222.445  230.426  533.4771  249.6535  261.322 3075.166    10
           fun5(x)  219.845  232.682  508.5585  253.7870  298.801 2775.606    10
           fun6(x) 1531.715 1597.888 2229.4907 1616.1170 1913.850 7245.782    10
          

          fun2 - fun5 的速度大致相同,fun4fun5 稍快一些。最初的解决方案(出乎意料)很慢。

          【讨论】:

          • 干得好。我假设 OP 想要一个类似于他们的audit 的列表作为输出。不过,Reduce 很慢这一事实非常有趣。
          • R 中的@Edward 函数调用在计算上可能会很昂贵,尤其是在创建新对象时(我从经验中知道这一点)。这就是为什么我预计 Reduce 解决方案会很慢。
          猜你喜欢
          • 2020-08-04
          • 2022-12-11
          • 2015-06-12
          • 2014-02-13
          • 2014-01-02
          • 2021-04-17
          • 1970-01-01
          • 2016-08-24
          相关资源
          最近更新 更多