【问题标题】:iterate over certain elements of a list, not a data.frame迭代列表的某些元素,而不是 data.frame
【发布时间】:2019-08-07 22:48:13
【问题描述】:

我正在尝试根据 render.data 列表中的条件(以“rr_esp”开头)修改列表中的某些项目。

library(tidyr)
library(dplyr)
library(purrr)

per <- 2015:2019
render.data <- list(
  emision = structure(
    list(
      AÑO = c(2017, 2018, 2019), 
      TRABAJADORESMES_r = c(58147, 57937, 24818), 
      MASA_r = c(3439195127, 4091347036.2, 2441068565.77), 
      TRABAJADORESMESsinDOM = c(58147L, 57928L, 24818L), 
      MESES = c(12, 12, 5)
    ), 
    class = c("tbl_df", "tbl", "data.frame"), 
    row.names = c(NA, -3L)
  ),
  siniestros = structure(
    list(
      AÑO = c(2017, 2018, 2019), 
      N = c(388L, 327L, 115L), 
      GR_66 = c(64, 53, 15), 
      JU = c(41L, 5L, 0L), 
      JN = c(20, 19, 6), 
      PORINC_66s = c(437.22, 293.73, 82.12), 
      EDADs = c(15142L, 12886L, 4712L), 
      SALARIOs = c(13707950.67, 15151144.7, 4800075.4)
    ), 
    class = c("tbl_df", "tbl", "data.frame"), 
    row.names = c(NA, -3L)
  ),
  rr_esp1 = structure(
    list(
      AÑO = c(2017, 2018, 2019), 
      MESES = c(12, 12, 5),
      TRAB_PROM = c(4845.58, 4828.08, 4963.60), 
      PORINC = c(6.83, 5.54, 5.47), 
      SALARIO = c(35329.76, 46333.77, 41739.78), 
      EDAD = c(39.02, 39.40, 40.97)
    ), 
    class = c("tbl_df", "tbl", "data.frame"), 
    row.names = c(NA, -3L)
  ),
  rr_esp7 = structure(
    list(
      AÑO = c(2017, 2018, 2019), 
      JUI_LIQ = c(1539624.21, 318726, 0), 
      JUI_RVA = c(24434809.51, 2292925.89, 0), 
      JUI_IBNR = c(0, 25284030.0174036, 22434092.26), 
      JUI_ULT = c(25974433.72, 27895681.90, 22434092.26), 
      CM_JUICIO = c(1505898.34, 1806002.14, 1557923.07)
    ), 
    class = c("tbl_df", "tbl", "data.frame"), 
    row.names = c(NA, -3L)
  )
)

当对它们的元素应用循环时,它们会丢失原来的项目名称 之后,我不知道有更好的方法来迭代列表元素的子集并为它们分配一个新值。我用谷歌搜索,但我没有找到 list 而不是 data.frames 的关键解决方案。

 render.data <- invisible(lapply(seq_along(render.data), function(i){
    if(startsWith(names(render.data)[i], prefix = "rr_esp")){
      render.data[[i]] %>% 
       complete(`AÑO` = per) %>% 
       gather(
         key = "metrica", value = "valor", -`AÑO`
       ) %>% 
       mutate(# orden de las metricas
         metrica = factor(metrica, levels = unique(metrica))
       ) %>% 
       spread(
         key = `AÑO`, value = "valor"
       )} else{
         render.data[[i]]
       }
      setNames(render.data[[i]], names(render.data)[i])
  }))

【问题讨论】:

  • 请提供一些示例数据。还包括相关的库调用 - 看起来像 tidyrdplyr,但最好确定一下。
  • 回声。我已经添加了
  • 我认为主要问题是你的函数没有return 任何东西。如果您有function(x) { x + 1; names(x) = "hello" },则计算x + 1,但该函数只返回"hello"。可能您希望function(x) { x &lt;- x + 1; names(x) &lt;- "hello"; return(x)} 修改x 值,修改x 名称,并返回修改后的值。

标签: r dplyr purrr


【解决方案1】:

这似乎是for 循环比lapply 更清晰的情况。 lapply 的主要优点是(a)它为结果预先分配了一个数据结构,并且(b)具有简单的语法来应用一个简单的函数。您已经有了结果的数据结构,并且您的函数很复杂。我不知道你的预期输出是什么,但我会试试这个:

# find elements to modify
rr_elements = which(startsWith(names(render.data), prefix = "rr_esp"))

# modify in for loop
for (i in rr_elements) {
  render.data[[i]] = render.data[[i]] %>%
    complete(`AÑO` = per) %>%
    gather(key = "metrica", value = "valor",-`AÑO`) %>%
    mutate(# orden de las metricas
      metrica = factor(metrica, levels = unique(metrica))) %>%
    spread(key = `AÑO`, value = "valor")
}

如果你想让这段代码更可重用,为一个数据帧的操作创建一个函数,然后你可以很容易地使用它forlapply。一般来说,我会说选择要使用该函数的数据帧外部内部更好。 (也就是说,我不喜欢你有一个 if() 语句来检查函数 inside 的名称。在函数 outside 执行这个逻辑,并且只给出函数您希望它使用的数据。)

foo = function(data) {
  data %>%
    complete(`AÑO` = per) %>%
    gather(key = "metrica", value = "valor",-`AÑO`) %>%
    mutate(# orden de las metricas
      metrica = factor(metrica, levels = unique(metrica))) %>%
    spread(key = `AÑO`, value = "valor")
}

# now the for loop or lapply is simple:
rr_elements = which(startsWith(names(render.data), prefix = "rr_esp"))

# for loop version
for (i in rr_elements) {
  render.data[[i]] = foo(render.data[[i]])
}

# lapply version
render.data[rr_elements] = lapply(render.data[rr_elements], foo)

【讨论】:

  • 谢谢!!从外部选择 data.frames 以避免重复 if 是一个很好的说明。当您根据其他是/否列对列 data.frame 进行变异时,我也有类似的疑问。我正在使用if_else 声明
猜你喜欢
  • 2019-04-18
  • 2023-04-04
  • 1970-01-01
  • 2019-10-16
  • 1970-01-01
  • 2019-02-13
  • 1970-01-01
  • 2021-07-16
  • 1970-01-01
相关资源
最近更新 更多