【问题标题】:Named list issue when using dplyr::recode within purrr::map2在 purrr::map2 中使用 dplyr::recode 时的命名列表问题
【发布时间】:2018-12-06 19:09:15
【问题描述】:

我一直在研究 R purrr 包,但遇到了障碍。我在下面创建了一些模拟数据,它们代表了我的数据实际外观的一个非常小的 sn-p。

library(tidyverse)

my_data <- tribble(
  ~lookup_lists, ~old_vectors,

  # Observation 1
  list(
    "X1" = "one",
    "X7" = "two", 
    "X16" = "three"
  ), 

  c("Col1", "Col2", "Col3", "X1", "X7", "X16"),

  # Observation 2
  list(
    "X3" = "one",
    "X8" = "two", 
    "X22" = "three"
  ), 

  c("Col1", "Col2", "Col3", "X3", "X8", "X22")
)

此时,我想创建一个与old_vectors 具有相同向量值但以 X 开头的值的新列,以反映@987654324 中的查找命名列表@。例如,我希望第一行来自:

c("Col1", "Col2", "Col3", "X1", "X7", "X16")

c("Col1", "Col2", "Col3", "one", "two", "three")

并保存到嵌套 tibble 中的新列。这是我使用map2 函数的尝试:

# Add a third column that has the recoded vectors

my_data <- my_data %>%
  mutate(new_vectors = map2(.x = old_vectors, .y = lookup_lists, .f = ~recode(.x, .y)))

#> Error in mutate_impl(.data, dots): Evaluation error: Argument 2 must be named, not unnamed.

我不明白这一点,因为第二个参数 IS 命名。这是第一个观察的 lookup_list 来说明我的观点:

my_data$lookup_lists[[1]]
$X1
[1] "one"

$X7
[1] "two"

$X16
[1] "three"

我认为我遗漏了一些非常明显的东西,可能与this 有关。任何帮助将不胜感激!

【问题讨论】:

    标签: r dictionary purrr


    【解决方案1】:

    由于'lookup_lists'是一个名为list,我们可以将unlist它命名为vector,用它来匹配'old_vectors'中的元素并替换 其值与“key”与“old_vector”中的元素相匹配。不匹配的将是NA。用na.omit 删除它并与'old_vectors' 中的'Col' 元素(使用grep)连接

    out <- my_data %>% 
               mutate(new_vectors = map2(old_vectors, lookup_lists,
             ~ c(grep('Col', .x, value = TRUE), unname(na.omit(unlist(.y)[.x])))))
    out$new_vectors
    #[[1]]
    #[1] "Col1"  "Col2"  "Col3"  "one"   "two"   "three"
    
    #[[2]]
    #[1] "Col1"  "Col2"  "Col3"  "one"   "two"   "three"
    

    【讨论】:

      【解决方案2】:

      它不起作用,因为recode 不能那样工作。要了解会发生什么,有助于简化您的示例:

      x <- my_data[["old_vectors"]]
      y <- my_data[["lookup_lists"]]
      recode(x[[1]], y[[1]])
      ## Error: Argument 2 must be named, not unnamed
      

      ?recode 中所述,该函数需要的不是命名的替换列表,而是一系列命名的参数。也就是说,它想要的不是recode(x[[1]], y[[1]])

      recode(x[[1]], X1 = "one", X7 = "two", X16 = "three")
      ## [1] "Col1"  "Col2"  "Col3"  "one"   "two"   "three"
      

      这种情况很常见,有一个标准的处理方法:

      invoke(recode, .x = y[[1]], x[[1]])
      ## [1] "Col1"  "Col2"  "Col3"  "one"   "two"   "three"
      

      现在我们知道如何将命名的参数列表传递给需要多个(可能命名的)参数的函数,我们可以应用这些知识来解决原始问题:

      my_data <- my_data %>%
          mutate(new_vectors = map2(.x = old_vectors, .y = lookup_lists,
                                    .f = ~invoke(recode, .x = .y, .x)))
      

      【讨论】:

        猜你喜欢
        • 2019-04-03
        • 1970-01-01
        • 1970-01-01
        • 2018-05-22
        • 2019-09-11
        • 1970-01-01
        • 2022-01-16
        • 2022-08-09
        • 2020-02-24
        相关资源
        最近更新 更多