【问题标题】:Using lapply over a list and adding a column with data frame name在列表上使用 lapply 并添加带有数据框名称的列
【发布时间】:2019-10-09 18:04:07
【问题描述】:

我有一个包含两个数据框的列表:

sample_list <- list("tables" = data.frame(weight = sample(1:50, 20, replace = T)),
                    "chairs" = data.frame(height = sample(1:50, 20, replace = T)))

我想使用lapply 对该列表中的所有数据框运行一个函数。在每个函数的输出中,我需要用源数据框的名称创建另一列(参见mutate):

lapply(sample_list, function(x) {
  x %>% 
    filter(x >= 20) %>% 
    mutate(groupName = names(x))
})

出于某种原因,我不知道如何进行这项工作。如何将数据框的名称传递给 mutate?现在它正在返回该数据框中第一列的名称,而不是数据框本身的名称。

谢谢!

【问题讨论】:

  • 使用Map(包装到mapply):Map(function(df, nm) df %&gt;% ... mutate(groupName = nm), sample_list, names(sample_list))

标签: r


【解决方案1】:

我们可以循环遍历sample_listnames,而不是遍历列表

lapply(names(sample_list), function(x) {
    sample_list[[x]] %>% 
        filter_at(vars(1),~. >= 20) %>% 
        mutate(groupName = x)
})

2021 年 9 月更新

使用purrr::map的更简洁的方式

purrr::map(names(sample_list), ~sample_list[[.x]] %>% 
             filter_at(vars(1),~. >= 20) %>% 
             mutate(groupName = .x)
)

【讨论】:

    【解决方案2】:

    您可以尝试purrr::imap() 映射元素和元素名称。

    # purrr::imap
    purrr::imap(sample_list, function(element,name){
        head(mutate(element,groupName = name))
    })
    
    # or mapply, but you need to specify names of the list
    myfun <- function(element,name){
        head(mutate(element,groupName = name))
    }
    
    mapply(myfun,sample_list,names(sample_list),SIMPLIFY = FALSE)
    
    
    $tables
      weight groupName
    1     42    tables
    2     24    tables
    3     13    tables
    4     31    tables
    5      9    tables
    6     27    tables
    
    $chairs
      height groupName
    1     18    chairs
    2      6    chairs
    3     34    chairs
    4     37    chairs
    5     36    chairs
    6     49    chairs
    

    【讨论】:

      【解决方案3】:

      使用来自base RMap

      Map(function(dat, grp) cbind(dat, group_name = grp)[dat[[1]] > 20,], 
                   sample_list, names(sample_list))
      

      【讨论】:

        【解决方案4】:

        您可以使用Mapdata.frame 函数来添加名称。

        Map(`data.frame`, sample_list, groupName = names(sample_list))
        #Map(`[<-`, sample_list, "groupName", value = names(sample_list)) #Alternative
        
        #$tables
        #   weight groupName
        #1      22    tables
        #2      12    tables
        #3       9    tables
        #4      26    tables
        #5      39    tables
        #6       6    tables
        #7      31    tables
        #8       9    tables
        #9      39    tables
        #10      4    tables
        #11     37    tables
        #12     30    tables
        #13     20    tables
        #14     35    tables
        #15     31    tables
        #16     46    tables
        #17     44    tables
        #18     30    tables
        #19     12    tables
        #20     46    tables
        #
        #$chairs
        #   height groupName
        #1      12    chairs
        #2      17    chairs
        #3      35    chairs
        #4      40    chairs
        #5      23    chairs
        #6      21    chairs
        #7      48    chairs
        #8      24    chairs
        #9      20    chairs
        #10     41    chairs
        #11     43    chairs
        #12     45    chairs
        #13     47    chairs
        #14     13    chairs
        #15     35    chairs
        #16     32    chairs
        #17     26    chairs
        #18     34    chairs
        #19     33    chairs
        #20      8    chairs
        

        如果它也应该被子集到那些&gt;= 20

        lapply(sample_list, function(x) x[x[,1] >= 20,, drop = FALSE])
        

        如果应该一步完成,我会使用@akrun 已经发布的方式。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-02-07
          • 2019-10-31
          • 2020-06-05
          • 2021-07-15
          • 2015-04-23
          • 2022-01-14
          • 2018-03-09
          相关资源
          最近更新 更多