使用来自dplyr的purrr和mutate()将新变量添加到数据框列表中

Rob*_*les 9 r dplyr purrr

我知道SO上有很多相关的问题,但我正在寻找一个purrr解决方案,请不要从应用程序列表或cbind/rbdind(我想借此机会更好地了解purrr)中找到解决方案.

我有一个数据框列表,我想为列表中的每个数据框添加一个新列.列的值将是数据帧的名称,即列表中每个元素的名称.

这里有类似的东西,但它涉及到函数的使用mutate_each(),而我只需要mutate().

为了让您了解列表(被调用comentarios),这是第str()一个元素的第一行:

> str(comentarios[1])
List of 1
 $ 166860353356903_661400323902901:'data.frame':    13 obs. of  7 variables:
Run Code Online (Sandbox Code Playgroud)

所以我希望我的新变量166860353356903_661400323902901在结果中包含13行,作为每个数据帧的ID.

我在想的是:

dff <- map_df(comentarios, 
              ~ mutate(ID = names(comentarios)),
              .id = "Group"
              )
Run Code Online (Sandbox Code Playgroud)

但是,mutate()需要数据帧的名称才能工作:

Error in mutate_(.data, .dots = lazyeval::lazy_dots(...)) : 
  argument ".data" is missing, with no default
Run Code Online (Sandbox Code Playgroud)

放入每个名字是没有意义的,我会陷入循环领域而失去了purrr(和更普遍的R)的优势.如果列表较小,我会使用reshape::merge_all(),但它有超过2000个元素.在此先感谢您的帮助.

编辑:根据alistaire的评论,一些数据可以使问题重现

# install.packages("tidyverse")
library(tidyverse)
df <- data_frame(one = rep("hey", 10), two = seq(1:10), etc = "etc")

list_df <- list(df, df, df, df, df)
names(list_df) <- c("first", "second", "third", "fourth", "fifth")
dfs <- map_df(list_df, 
              ~ mutate(id = names(list_df)),
              .id = "Group"
              )
Run Code Online (Sandbox Code Playgroud)

Jak*_*upp 14

您的问题是,当您不在管道中使用mutate时,必须明确提供对数据的引用.要做到这一点,我建议使用map2_df

dff <- map2_df(comentarios, names(comentarios), ~ mutate(.x, ID = .y)) 
Run Code Online (Sandbox Code Playgroud)

  • 仅供参考,从 *purrr_0.2.3* 开始,当您想同时循环遍历列表和列表的名称(或索引)时,有一个“简写”系列的“imap”索引函数。 (2认同)

use*_*rJT 5

使用 OP 的数据,答案是

library(tidyverse)
df <- data_frame(one = rep("hey", 10), two = seq(1:10), etc = "etc")

list_df <- list(df, df, df, df, df)
dfnames <- c("first", "second", "third", "fourth", "fifth")

dfs <- list_df %>% map2_df(dfnames,~mutate(.x,name=.y))
Run Code Online (Sandbox Code Playgroud)