【问题标题】:Attach the name of each dataframe as a column after looping over a list of dataframes in R循环遍历 R 中的数据框列表后,将每个数据框的名称附加为一列
【发布时间】:2021-04-01 13:57:21
【问题描述】:

我创建了一个数据框列表。我需要遍历它们,过滤我需要的内容并保存为单个文件。 但是,我需要从每个文件中了解每个值的来源。

每个数据框都有一个名称,例如 Plastic Chair 1111、Wooden Chair 3950、Table 6909 等...并保存在名为“listed”的列表中,该列表包含以下结构:

listed[1]

Material_ID  ABC  Key.Figure   W01  W02  W03
46548970     A    Actuals     1048  564  548
46548970     A    Forecasted  848   500  590 
18969856     A    Actuals     358   1500 900 
18969856     A    Forecasted  460   1602 1000

listed[2]

Material_ID  ABC  Key.Figure   W01  W02  W03
24564897     A    Actuals     1258  444  798
26548970     A    Forecasted  1345  500  850 
34879856     A    Actuals      985  1020 980 
15486856     A    Forecasted   846  1064 1100

我想得到的是:

   Group name  Group Code Material_ID  ABC  Key.Figure   W01  W02  W03
   Plastic Chair   1111   46548970     A    Actuals     1048  564  548
   Plastic Chair   1111   18969856     A    Actuals     358   1500 900 
    Wooden Chair   3950   24564897     A    Actuals     1258  444  798
    Wooden Chair   3950   34879856     A    Actuals      985  1020 980 

是否可以使用数据框名称在左侧创建这两列?

非常感谢您的帮助!

如果您需要更好地了解情况,这是我的代码。

library(openxlsx)
library(dplyr)
library(purrr)

# read the data
filename = 'Dataset.xlsx'
wb <- loadWorkbook(filename)

# get a list of the spreadshits in the excel file
sheetNames <- sheets(wb)
sheetNames <- make_names(sheetNames)

# create an empty list
listed <- list()

# assign which spreadshit as a dataframe inside a list
for(i in 1:length(sheetNames))
{
  listed[[i]] <- assign(sheetNames[i],readWorkbook(wb,sheet = i))
  print(paste0("read the ", i," file")) # here it says what it's doing
}

# remove variable Sales.Org.ID
map(listed, ~ (.x %>% select(-Sales.Org.ID)))

# filter the dataframes to only show rows with Key.Figure = "Actual Totals"
list_actuals <- lapply(listed, function(x) x %>%
                         filter( Key.Figure == "Actual Totals"),
  )

# put the result in a single dataframe  
result_actuals = do.call(rbind,list_actuals)

【问题讨论】:

  • 您是否看过purrr::map_dfr,它适用于使用.id 参数附加数据框名称的命名数据框列表?
  • 如果没有最小的可重现示例,很难提供答案。我会注意到,您现在可以将数据框放在带有列表列的更大数据框的列中。如果您有一列包含数据框的名称,则可以添加一个名为 data 的列,其中包含每个数据框,然后变异一个函数来进行过滤,然后在变异列上执行 rbind

标签: r list dataframe spreadsheet


【解决方案1】:

我认为稍微简化代码会有所帮助。例如,不要先用make_names 更改工作表名称,然后遍历工作表编号以导入。相反,在导入数据之前使用未更改的工作表名称,并在以后根据需要更改名称。也可以尝试map_df,而不是lapply 后跟rbind。它不像 cmets 中建议的 purrr::mapdfr 那样专业,但更容易看到正在发生的事情。在下面的示例代码中,我在map_df 中使用了mutatemap_df 组合它们之前将名称插入每个数据框。

library(openxlsx)
library(dplyr)
library(purrr)

# read the data
filename = 'Dataset.xlsx'
wb <- loadWorkbook(filename)

wb %>%
    sheets() %>%

    # read all of the sheets, put the sheet name in a new column
    map_df(~readWorkbook(wb, sheet = .x) %>% mutate(group_name = .x)) %>%
    
    # remove variable Sales.Org.ID
    select(-Sales.Org.ID) %>%

    # filter the dataframes to only show rows with Key.Figure = "Actual Totals"
    filter( Key.Figure == "Actual Totals") %>%

    # if you still want to change the names taken from the sheet names
    mutate(group_name = make_name(group_name))

【讨论】:

  • 非常感谢所有提示和帮助。我尝试使用您的代码,但出现错误:mutate() 输入 group_name 出现问题。 x Objekt '.x' nicht gefunden i 输入group_name.x
  • 看起来readWorkbook(...) 后面多了一个括号。我编辑了答案以修复它
  • 我已经看到了额外的括号并更正了它。这不是导致我的错误的原因......
  • 如果没有手头的实际数据(或可以创建可重现的错误示例的代码),很难确认,但根据我能看到或猜到的内容,我确实有一些要检查的建议. ~ 可能在 map() 步骤内的代码开头丢失。显示的示例数据没有名为“Sales.Org.ID”的列。最后,这里没有定义make_names()函数,或许应该是make.names()吧?
  • 你是对的!函数 make_name 的名称中缺少“s”。非常感谢您的帮助!我也达到了结果,但是您的解决方案更干净,执行得更好,这也有助于我学习。也感谢您花时间解决问题...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-20
  • 2018-09-28
  • 2021-02-08
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多