Разверните вложенные элементы списка в data.table в R в соответствии со вторым столбцом списка

У меня есть таблица данных в R, которая

> data.table(value = "one",list1=list(c(list("one1"),list("one2"),list(c("one3 1","one3 2")))),position=list(c(0,1,2)))
     value     list1  position
  1:   one <list[3]>     0,1,2

где элемент <list[3]>

[[1]]
[[1]][[1]]
[1] "one1"

[[1]][[2]]
[1] "one2"

[[1]][[3]]
[1] "one3 1" "one3 2"

Я хочу удлинить таблицу данных, чтобы у меня было

value   list1     position
one     "one1"    0
one     "one2"    1
one     "one3 1"  2
one     "one3 2"  2

где «one3 2» соответствует позиции 2. До сих пор все мои попытки приводили к тому, что позиция 3 была указана для «one3 2». Это можно как-то исправить?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
86
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вот один из вариантов, если это ваш фактический набор данных, хотя вы не уверены в другой логике, которая может применяться к вашим данным:

library(data.table)
library(tidyverse)

dt <- data.table(
  value = "one",
  list1=list(c(list("one1"),list("one2"),list(c("one3 1","one3 2")))),
  position=list(c(0,1,2))
  )

dt %>% 
  tidyr::unnest_longer(c(list1, position)) %>% 
  tidyr::unnest_longer(list1) %>% 
  dplyr::mutate(temp_index = readr::parse_number(list1) - 1) %>% 
  dplyr::filter(position == temp_index) %>% 
  dplyr::select(-temp_index)

#> # A tibble: 4 × 3
#>   value list1  position
#>   <chr> <chr>     <dbl>
#> 1 one   one1          0
#> 2 one   one2          1
#> 3 one   one3 1        2
#> 4 one   one3 2        2

Unnest может обрабатывать несколько столбцов при условии, что каждый из них не вложен в одинаковую длину, поэтому вы можете упростить это решение до двух вызовов unnest. dt %>% unnest_longer(c(list1, position)) %>% unnest_longer(list1).

Ritchie Sacramento 21.04.2023 06:03
Ответ принят как подходящий

Использование data.table

library(data.table)
 dt1[, .(value, list1 = unlist(list1),
   position = c(mapply(\(x, y) rep(x, lengths(y)), position, list1)))]

-выход

    value  list1 position
1:   one   one1        0
2:   one   one2        1
3:   one one3 1        2
4:   one one3 2        2

Спасибо, я только что понял, что у моего dt1 есть list1 значения, которые представляют собой пустые списки. Это приводит к ошибке Error in rep(x, lengths(y)) : invalid 'times' argument. У вас есть идеи, как я могу учитывать пустые списки, которые затем приводят к нулевой длине?

user321627 21.04.2023 08:08

@ user321627, вы хотите удалить эти пустые дела или вернуть NA?

akrun 21.04.2023 08:43

@user321627 user321627 можете показать пример. Этот пример dt2 <- data.table(value = "one",list1=list(c(list("one1"),list(NULL),‌​list(c("one3 1","one3 2")))),position=list(c(0,1,2))) работает с кодом

akrun 21.04.2023 08:45

@ user321627 можешь попробовать yourdat[, c(.(value = value), lapply(seq_along(list1), \(i) {x <- list1[[i]]; l1 <- lengths(x); x[l1==0] <- NA_character_; data.table(list1 = unlist(x), position = rep(position[[i]], lengths(x)))}))]

akrun 21.04.2023 08:56

Я думаю, вы можете использовать unnest дважды, как показано ниже.

dt %>%
  unnest(c(list1, position)) %>%
  unnest(list1)

который дает

# A tibble: 4 × 3
  value list1  position
  <chr> <chr>     <dbl>
1 one   one1          0
2 one   one2          1
3 one   one3 1        2
4 one   one3 2        2

Вот еще один необычный подход, основанный только на data.table:

dt[, .(value, list1 = unlist(list1, recursive = FALSE), position = unlist(position))][, .(list1 = unlist(list1)), by = .(value, position)]
#>    value position  list1
#> 1:   one        0   one1
#> 2:   one        1   one2
#> 3:   one        2 one3 1
#> 4:   one        2 one3 2

или немного проще:

dt[, .(value, list1 = list1[[1]], position = position[[1]])][, .(list1 = unlist(list1)), by = .(value, position)]
#>    value position  list1
#> 1:   one        0   one1
#> 2:   one        1   one2
#> 3:   one        2 one3 1
#> 4:   one        2 one3 2

Другие вопросы по теме