使用purrr和dplyr中的mutate()向数据框列表中添加新变量。

14

我知道在SO上有很多相关的问题,但我正在寻找一个purrr解决方案,而不是apply函数列表或cbind / rbdind(我想借此机会更好地了解purrr)。

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

这里有一个类似的问题(链接),但它涉及使用函数和mutate_each(),而我只需要mutate()

为了让你了解列表(名为comentarios),这里是str()在第一个元素上的第一行:

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

我希望我的新变量作为每个数据框的ID,在结果中包含13行,其值为166860353356903_661400323902901

我尝试的方法是:

dff <- map_df(comentarios, 
              ~ mutate(ID = names(comentarios)),
              .id = "Group"
              )

然而,mutate()需要数据框的名称才能正常工作:

Error in mutate_(.data, .dots = lazyeval::lazy_dots(...)) : 
  argument ".data" is missing, with no default
在每个名称中进行处理没有意义,这样会陷入循环范围并失去purrr(和R更普遍)的优势。如果列表较小,我将使用reshape :: merge_all(),但它有超过2000个元素。提前感谢您的任何帮助。 < p >编辑:根据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"
              )

你需要添加数据来使你的示例可重现 - alistaire
我认为这里不必要,Alistaire,这是一个关于语法的问题,正如Jake的回答所示。 - RobertMyles
2
请提供最小化、完整的可重现代码,否则问题将被关闭。[提问] - alistaire
我的错误,现已修复。 - RobertMyles
更好的做法是,你应该展示一下你期望的输出。假设一下,你可以直接使用 dplyr::bind_rows(list_df, .id = 'id') - alistaire
2个回答

21

你的问题在于,当你不使用管道操作符来进行数据修改时,需要显式地提供对数据的引用。为了解决这个问题,我建议使用map2_df函数。

dff <- map2_df(comentarios, names(comentarios), ~ mutate(.x, ID = .y)) 

这只是对两个参数进行映射。第一个参数是.x数据框列表,第二个参数是.y数据框名称列表。 - Jake Kaupp
当然,但我没想到我可以用那种方式做到,这就是我的意思。这正是为什么我要求一个 purrr 的答案,因为我想更好地了解这个包。再次感谢你的帮助。 - RobertMyles
@JakeKaupp - 这部分的意思是什么:".id = "Group"。当我省略它时,代码仍然可以正常工作。 - Tomasz Mikolajczyk
这是一个打字错误和括号放错了位置。'. id' 是 OP 问题中的经济变量。 - Jake Kaupp
2
请注意,从 purrr_0.2.3 开始,当您想要循环遍历列表并同时获取列表的名称(或索引)时,有一组“简写” imap 索引函数可供使用。 - aosmith

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))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接