【问题标题】:How do I add columns to a list of dataframes using paste0() in R?如何在 R 中使用 paste0() 将列添加到数据框列表中?
【发布时间】:2020-01-29 23:49:34
【问题描述】:

我有一个名为 list_of_sheets 的 2 个数据框列表。这些数据框是来自具有相同列名的 Excel 工作表的数据。以下是相关列的快照。

List of 2
 $ :Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   242 obs. of  43 variables:
  ..$ Market Section     : num [1:242] 559286 559287 559286 559287 559287 ...
  ..$ Market Section Name: chr [1:242] "DOMESTIC BULK CUSTOMER MARKET SECTION" "INTERNATIONAL BULK MARKET SECTION" "DOMESTIC BULK CUSTOMER MARKET SECTION" "INTERNATIONAL BULK MARKET SECTION" ...
  ..$ JDE Branch Plant   : chr [1:242] "PBK0100" "PBK0200" "PBK0200" "PNR0100" ...
  ..$ Short Item Code    : num [1:242] 2085010 1782171 1782059 1823261 1934471 ...
  ..$ Long Item Code     : chr [1:242] "016144" "637524" "554326" "149226" ...

我正在尝试创建一个键列,该列将是 JDE 分厂、长项目代码和市场部分列的串联。

以下是我尝试过的一些方法。我是 R 的初学者,我对使用 apply() 函数和使用列表的知识有限,因此我感谢提供的任何帮助。我想对于那些有更多经验的人来说,我犯了一个明显的错误。

list_of_sheets <- mapply(cbind, list_of_sheets, "Key" = paste0(`JDE Branch Plant`, `Long Item Code`, `Market Section`))

for (i in seq_along(list_of_sheets)) {
  list_of_sheets[[i]]$Key <- paste0(`JDE Branch Plant`, `Long Item Code`, `Market Section`)

  }

对于这两个,我得到以下错误。

Error in paste0(`JDE Branch Plant`, `Long Item Code`, `Market Section`) : 
  object 'JDE Branch Plant' not found

我相信也可能有 purrr 解决方案,但我对包了解不多。 如果有人推荐资源来深入理解 R 中的 apply 和 purrr 函数,我也将不胜感激。

【问题讨论】:

    标签: r for-loop lapply purrr mapply


    【解决方案1】:

    由于它是tbl_df,我们可以使用tidyverse 方法,即循环使用listmap,在指定remove = FALSE 的同时通过unite 相关列创建“键”列(如果不再需要这些列,则默认为remove = TRUE

    library(dplyr)
    library(purrr)
    library(tidyr)
    list_of_sheets2 <- list_of_sheets %>%
         map(~ .x %>%
                    unite(Key, `JDE Branch Plant`,
                 `Long Item Code`, `Market Section`, remove = FALSE, sep=""))
    

    在 OP 的代码中,问题在于它只是 pasteing 列名而不是这些列中的值。我们可以使用[[提取每个数据集的列

    for (i in seq_along(list_of_sheets)) {
        list_of_sheets[[i]]$Key <- paste0( list_of_sheets[[i]][["JDE Branch Plan"]],  
         list_of_sheets[[i]][["Long Item Code"]], 
         list_of_sheets[[i]][["Market Section"]])
    
     }
    

    或者可以使用with将其缩短一点

    for (i in seq_along(list_of_sheets)) {
        list_of_sheets[[i]]$Key <-
             with(list_of_sheets[[i]], paste0(`JDE Branch Plant`,
              `Long Item Code`, `Market Section`))
    
       }
    

    OP 也尝试使用mapply 并遇到同样的问题。在这种情况下,我们不需要mapply,因为Map/mapply 用于与相应元素的转换。在这里,每个list 元素都具有相同的列,并且需要对这些相同的列进行转换。相反,可以使用lapply

    list_of_sheets2 <- lapply(list_of_sheets, transform,
            Key = paste0(`JDE Branch Plant`, `Long Item Code`, `Market Section`))
    

    【讨论】:

    • 非常感谢您的帮助。这些解决方案效果很好,尽管我无法让第一个 for 循环工作。 R 找不到列名。只是为了我的学习目的,我很好奇你为什么在 lapply 解决方案中使用 transform() 。我在“帮助”部分查找了它,但不确定。
    • @LauraDR 抱歉,我没有测试它,因为没有可重现的示例。您能否更改更新的代码,即在 for 循环中将列名的反引号更改为单引号或双引号
    • @LauraDR transform 是为了避免使用匿名函数调用,即.. lapply(list_of_sheets, function(dat) {dat$Key &lt;- with(dat, paste0(JDE Branch Plant, Long Item Code, Market Section)); dat}) as transform可以直接评估我们是否给出不带引号的列名(如果有空格或不自然的名称,则使用反引号)'
    猜你喜欢
    • 2015-04-23
    • 2015-06-29
    • 2021-04-17
    • 2017-11-27
    • 1970-01-01
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多