У меня есть список с именами элементов типа x.height, x.weight, y.height, y.length, z.weight, z.price Я хотел бы извлечь элементы, имена которых начинаются с "x." и переименовать эти элементы, удалив их префикс "x.". Это можно сделать в два этапа:

list.new <- list.old %>% keep(str_detect(names(.), "^x.")) 
names(list.new) <- str_replace(names(list.new), "x", "")

Мой первый вопрос: как объединить эти два этапа в конвейер?

В конце я хотел бы обработать список для всех различных префиксов "y.", "z.", чтобы получить новый список с переименованными подсписками, например:

List of 3
 $ x:List of 2
  ..$ height: num 100
  ..$ weight: num 200
 $ y:List of 2
  ..$ height: num 300
  ..$ length: num 400
 $ z:List of 2
  ..$ weight: num 500
  ..$ price: num 600

Возможно ли это сделать с помощью одного трубопровода?

Hi CLH

Ответов: 2

Ответы (2)

Вы можете просто использовать setNames() или set_names():

list.old <- list(
  x.height=1, x.weight=2, y.height=3, y.length=4, z.weight=5, z.price=6
)

list.old %>%
  keep(startsWith(names(.), prefix)) %>%
  set_names(str_replace(names(.), prefix, ""))
# $height
# [1] 1
# 
# $weight
# [1] 2

Для применения ко многим префиксам используйте предыдущий код в качестве функции:

prefix_list <- c("x","y","z")

map(prefix_list,
    function(prefix) list.old %>%
      keep(startsWith(names(.), prefix)) %>%
      set_names(str_replace(names(.), prefix, ""))
) %>%
  set_names(prefix_list)
# $x
# $x$.height
# [1] 1
# 
# $x$.weight
# [1] 2
# 
# 
# $y
# $y$.height
# [1] 3
# 
# $y$.length
# [1] 4
# 
# 
# $z
# $z$.weight
# [1] 5
# 
# $z$.price
# [1] 6

Вы можете добиться желаемого следующим способом. Обратите внимание, что для этого необходимо, чтобы у вас была последняя версия пакета dplyr (>= 1.0.0).

library(dplyr)
library(stringr)
library(purrr)

list.old <- list(
  x = list(x.height = 100, x.weight = 200),
  y = list(y.height = 300, y.length = 400),
  z = list(z.weight = 500, z.price = 600)
)

list.new <- list.old %>%
  map(as_tibble) %>%
  map(~ rename_with(.x, ~ str_remove(.x, "^[xyz]\\."))) %>%
  map(as.list)

str(list.new)

List of 3
 $ x:List of 2
  ..$ height: num 100
  ..$ weight: num 200
 $ y:List of 2
  ..$ height: num 300
  ..$ length: num 400
 $ z:List of 2
  ..$ weight: num 500
  ..$ price : num 600

2022 WebDevInsider