【问题标题】:More efficient way to purrr::map2 for a large dataframe用于大型数据帧的更有效的 purrr::map2 方法
【发布时间】:2021-12-16 08:24:52
【问题描述】:

是否有更快的方法来执行以下操作,在实际应用程序中,df 有很多行(因此list_of_colnames 有相同数量的元素):

list_of_colnames <- list(c("A", "B"), c("A"))
some_vector <- c("fish", "cat")

map2(split(df, seq(nrow(df))), list_of_colnames, function(row, colnames) {
    row$indicator <- ifelse(any(row[, colnames] %in% some_vector), 1, 0)
    return(row)
  })

虽然当前的实现有效,但大型 df 需要几个世纪的时间。事实上,我认为split() 是一个主要瓶颈。

谢谢!

【问题讨论】:

    标签: r list dataframe purrr


    【解决方案1】:

    您可以避免将数据框拆分为一个列表,而是使用来自dplyrrowwisec_across 跨行应用您的条件:

    library(dplyr)
    library(purrr)
    
    list_of_colnames <- list(c("A", "B"), c("A"))
    some_vector <- c("fish", "cat")
    
    map(list_of_colnames, ~ 
          df %>% 
          rowwise() %>% 
          mutate(indicator = as.numeric(any(c_across(all_of(.x)) %in% some_vector))) %>% 
          ungroup()
        )
    

    输出

    仍然映射list_of_columns 会返回一个列表输出:

    [[1]]
    # A tibble: 3 x 4
      A     B     C     indicator
      <chr> <chr> <chr> <lgl>    
    1 fish  dog   bird  TRUE     
    2 dog   cat   bird  TRUE     
    3 bird  lion  cat   FALSE    
    
    [[2]]
    # A tibble: 3 x 4
      A     B     C     indicator
      <chr> <chr> <chr> <lgl>    
    1 fish  dog   bird  TRUE     
    2 dog   cat   bird  FALSE    
    3 bird  lion  cat   FALSE  
    

    数据

    structure(list(A = c("fish", "dog", "bird"), B = c("dog", "cat", 
    "lion"), C = c("bird", "bird", "cat")), class = "data.frame", row.names = c(NA, 
    -3L))
    

    【讨论】:

      【解决方案2】:

      一种选择可能是使用row/column 索引

      rowind <- rep(seq_len(nrow(df)), lengths(list_of_colnames) * nrow(df))
      df$indicator <- +(tapply(c(t(df[unlist(list_of_colnames)])) %in% some_vector,
             rowind, FUN = any))
      

      -输出

      > df
            A   B indicator
      1  fish   A         1
      2 hello cat         1
      

      数据

      df <- data.frame(A =  c('fish', 'hello'), B = c('A', 'cat'))
      

      【讨论】:

      • 谢谢@akrun!虽然当我尝试设置df &lt;- data.frame(A = c('foo', 'hello'), B = c('A', 'cat')) 然后我得到&gt; df`A B 指标`1 foo A 12 hello cat 0
      • @Alex 我更新了我的示例和代码。你能检查一下吗
      • 嗯,它似乎还在做同样的事情?
      • @Alex 我得到&gt; df$indicator [1] 1 1
      • 我的意思是我得到了 1 1。我的控制台之前有一个混淆,但代码似乎都得到了 1s
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-07
      • 2019-09-11
      • 1970-01-01
      • 2021-02-16
      • 2018-05-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多