Как я могу сделать объект списка в dataframe в длинном формате с Tidyverse в R - PullRequest
0 голосов
/ 04 марта 2020
dd <- list(c("2020-1-2","SDF","fff,33"),
           c("2020-1-3","KKK","ffd,23","fffdf,23","ssfds,43"))
dd
# [[1]]
# [1] "2020-1-2" "SDF"      "fff,33"  

# [[2]]
# [1] "2020-1-3" "KKK"      "ffd,23"   "fffdf,23" "ssfds,43"

ddtarget <- data.frame(date= c("2020-1-2","2020-1-3","2020-1-3","2020-1-3"),
                       category = c("SDF","KKK","KKK","KKK"),
                       element = c("fff,33","ffd,23","fffdf,23","ssfds,43"))
ddtarget
#       date category  element
# 1 2020-1-2      SDF   fff,33
# 2 2020-1-3      KKK   ffd,23
# 3 2020-1-3      KKK fffdf,23
# 4 2020-1-3      KKK ssfds,43

Я хочу преобразовать dd в ddtarget с помощью tidyverse, например map () или аналогичных функций, но я не могу сделать это самостоятельно. Может кто-нибудь мне помочь?

Ответы [ 3 ]

2 голосов
/ 04 марта 2020

Если первым элементом всегда является date, а вторым элементом всегда является category, а оставшимися элементами всегда является element, вы можете сделать следующее:

do.call(rbind, lapply(dd, function(x) {
  data.frame(date = x[1L], category = x[2L], element = tail(x, -2L))
}))
#       date category  element
# 1 2020-1-2      SDF   fff,33
# 2 2020-1-3      KKK   ffd,23
# 3 2020-1-3      KKK fffdf,23
# 4 2020-1-3      KKK ssfds,43

Если length(dd) велико, вы можете рассмотреть возможность использования data.table::rbindlist, который гораздо более оптимизирован, чем do.call(rbind): data.table::rbindlist(lapply(...))

Я также подозреваю, что ранее в вашем конвейере что-то не так - где это было dd родом из? Почему он принимает этот формат?

Если у вас есть контроль над шагами, которые создали dd, вы могли бы рассмотреть более целостное проектирование вашего конвейера.

2 голосов
/ 04 марта 2020

Предполагая, что первые два столбца всегда имеют длину 1, а третий столбец - все остальные элементы, здесь можно использовать map_df

purrr::map_df(dd,~tibble(date = .x[1], category = .x[2],element = .x[3:length(.x)]))

# A tibble: 4 x 3
#  date     category element 
#  <chr>    <chr>    <chr>   
#1 2020-1-2 SDF      fff,33  
#2 2020-1-3 KKK      ffd,23  
#3 2020-1-3 KKK      fffdf,23
#4 2020-1-3 KKK      ssfds,43
1 голос
/ 04 марта 2020

Другой вариант - unnest_wider с pivot_longer

library(tibble)
library(dplyr)
library(tidyr)
library(stringr)
tibble(dat = dd) %>%
   unnest_wider(c(dat), names_repair = ~c('date', 'category', str_c('V', 3:length(.)))) %>%
   pivot_longer(cols = V3:V5, values_to = "element", values_drop_na = TRUE) %>%
   select(-name)
# A tibble: 4 x 3
#  date     category element 
#  <chr>    <chr>    <chr>   
#1 2020-1-2 SDF      fff,33  
#2 2020-1-3 KKK      ffd,23  
#3 2020-1-3 KKK      fffdf,23
#4 2020-1-3 KKK      ssfds,43
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...