簡體   English   中英

使用Modify_depth和Modify_if(purrr)根據深度和if條件將元素插入列表中

[英]Insert elements into a list based on depth and `if` conditions using modify_depth and modify_if (purrr)

我正在學習一些purrr命令,特別是modify_*系列函數。 我正嘗試在雜貨店中找到的商品中添加price箱(請參見下文,了解我的嘗試和錯誤代碼)。

library(tidyverse)

數據

easybuy <- list(
  "5520 N Division St, Spokane, WA 99208, USA",
  list("bananas", "oranges"),
  canned = list("olives", "fish", "jam"),
  list("pork", "beef"),
  list("hammer", "tape")
) %>%
  map(list) %>%
  # name the sublists
  set_names(c("address",
              "fruit",
              "canned",
              "meat",
              "other")) %>%
  # except for address, names the sublists "items"
  modify_at(c(2:5), ~ set_names(.x, "items"))

看一眼:

glimpse(easybuy)
#> List of 5
#>  $ address:List of 1
#>   ..$ : chr "5520 N Division St, Spokane, WA 99208, USA"
#>  $ fruit  :List of 1
#>   ..$ items:List of 2
#>   .. ..$ : chr "bananas"
#>   .. ..$ : chr "oranges"
#>  $ canned :List of 1
#>   ..$ items:List of 3
#>   .. ..$ : chr "olives"
#>   .. ..$ : chr "fish"
#>   .. ..$ : chr "jam"
#>  $ meat   :List of 1
#>   ..$ items:List of 2
#>   .. ..$ : chr "pork"
#>   .. ..$ : chr "beef"
#>  $ other  :List of 1
#>   ..$ items:List of 2
#>   .. ..$ : chr "hammer"
#>   .. ..$ : chr "tape"

我的嘗試

想法:深入兩個,然后尋找“項目”,附加一個“價格”。 我不確定是否可以嵌套這樣的modify功能。

easybuy %>% 
  modify_depth(2, ~ modify_at(., "items", ~ append("price")))
#> Error: character indexing requires a named object

期望

我想要以下結構( 請注意在每個項目下添加了“價格” ):

List of 5
 $ address:List of 1
  ..$ : chr "5520 N Division St, Spokane, WA 99208, USA"
 $ fruit  :List of 1
  ..$ items:List of 2
  .. ..$ :List of 2
  .. .. ..$ : chr "bananas"
  .. .. ..$ : chr "price"
  .. ..$ :List of 2
  .. .. ..$ : chr "oranges"
  .. .. ..$ : chr "price"
 $ canned :List of 1
  ..$ items:List of 3
  .. ..$ :List of 2
  .. .. ..$ : chr "olives"
  .. .. ..$ : chr "price"
  .. ..$ :List of 2
  .. .. ..$ : chr "fish"
  .. .. ..$ : chr "price"
  .. ..$ :List of 2
  .. .. ..$ : chr "jam"
  .. .. ..$ : chr "price"
 $ meat   :List of 1
  ..$ items:List of 2
  .. ..$ :List of 2
  .. .. ..$ : chr "pork"
  .. .. ..$ : chr "price"
  .. ..$ :List of 2
  .. .. ..$ : chr "beef"
  .. .. ..$ : chr "price"
 $ other  :List of 1
  ..$ items:List of 2
  .. ..$ :List of 2
  .. .. ..$ : chr "hammer"
  .. .. ..$ : chr "price"
  .. ..$ :List of 2
  .. .. ..$ : chr "tape"
  .. .. ..$ : chr "price"

這似乎有效。 map_iffunction(x) !is.null(names(x))確保僅在項目名稱不為NULL時才進行更改。 ~modify_depth(.x, 2, function(y) list(y, "price"))創建您需要的列表。

library(tidyverse)

easybuy2 <- easybuy %>%
  map_if(function(x) !is.null(names(x)),
         ~modify_depth(.x, 2, function(y) list(y, "price")))

這是第二項的外觀。

easybuy2[[2]][[1]]
# [[1]]
# [[1]][[1]]
# [1] "bananas"
# 
# [[1]][[2]]
# [1] "price"
# 
# 
# [[2]]
# [[2]][[1]]
# [1] "oranges"
# 
# [[2]][[2]]
# [1] "price"

或這也可行。

easybuy3 <- easybuy %>% 
  modify_at(2:5, ~modify_depth(.x, 2, function(y) list(y, "price")))

identical(easybuy2, easybuy3)
# [1] TRUE

更新

easybuy4 <- easybuy %>%
  map_if(function(x){
    name <- names(x) 
    if(is.null(name)){
      return(FALSE)
    } else {
      return(name %in% "items")
    }
  },
~modify_depth(.x, 2, function(y) list(y, "price")))

identical(easybuy2, easybuy4)
# [1] TRUE

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM