Есть ли функция R для добавления списков с неравными столбцами - PullRequest
0 голосов
/ 04 мая 2019

У меня есть списки ниже (также с подсписками).Но здесь столбцы неравны.«a» список имеет 2 столбца, а «b» список имеет 3 столбца.

f <- list(a=list(1,2.5,9.5),b=list("2","-true","3",4))

Мне нужно добавить этот список, сохраняя ссылки, как показано ниже.Например,

COl1  COl2  COl3  Col4
 a     1    false   NA
 b     2    true    3

Как вы можете видеть выше, в столбце 1 есть ссылка, откуда берется объект данных из списков.Пожалуйста, руководство

Ответы [ 3 ]

1 голос
/ 04 мая 2019

1) data.table Установить имена в списке, дающем новый список fnam, а затем использовать rbindlist из data.table:

library(data.table)

fnam <- lapply(f, function(x) setNames(x, paste0("COL", seq(2, length = length(x)))))
cbind(COL1 = names(f), rbindlist(fnam , fill = TRUE))

, дающего:

   COL1 COL2  COL3 COL4
1:    a    1 false <NA>
2:    b    2  true    3

2) base R В этой альтернативе нет пакетов.Мы создаем символьный вектор из f и затем читаем его, используя read.table.

Lines <- paste(names(f), sapply(f, paste, collapse = " "))
nc <- max(lengths(f)) + 1
col.names <- paste0("COL", seq_len(nc))
read.table(text = Lines, header = FALSE, fill = TRUE, col.names = col.names)

, давая:

  COL1 COL2  COL3 COL4
1    a    1 false   NA
2    b    2  true    3

Используйте некоторый разделитель, который не появляется в данных, еслиданные могут содержать пробелы.

1 голос
/ 04 мая 2019

Одним из вариантов будет установка names элементов list с использованием map и указание .id в качестве 'COL1' для создания нового столбца на основе names из 'f'. Обратите внимание, что map возвращает list, а map_df a tb_df/data.frame

1)

library(tidyverse)
f %>%
   map_df(~ set_names(., paste0("COL", seq_along(.)+1)), .id = 'COL1')
# A tibble: 2 x 4
#  COL1   COL2 COL3  COL4 
#  <chr> <dbl> <chr> <chr>
#1 a         1 false <NA> 
#2 b         2 true  3 

2) Если типы различаются, retype (из hablar) и затем

library(hablar)
f1 %>%
   map_df(~ set_names(.x, paste0("COL", seq_along(.)+1))  %>% 
            map(retype), .id = 'COL1')
# A tibble: 2 x 4
#  COL1   COL2 COL3   COL4
#  <chr> <int> <chr> <int>
#1 a         1 false    NA
#2 b         2 true      3

3) или с type.convert

f1 %>%
   map_df(~ map(.x, type.convert, as.is = TRUE) %>% 
           set_names(paste0("COL", seq_along(.x))), .id = "COL1")
# A tibble: 2 x 4
#  COL1   COL1 COL2   COL3
#   <chr> <int> <chr> <int>
#1 a         1 false    NA
#2 b         2 true      3

4) , если integer/numeric создает проблему, преобразуйте ее в общий тип, т.е. до numeric

f1 %>%
  map_df(~ map(.x, type.convert, as.is = TRUE) %>% 
            map_if(is.integer, as.numeric) %>%
            set_names(paste0("COL", seq_along(.x))), .id = "COL1")

5) Поскольку типы смешаны, может быть лучше сделать retype после преобразования в один data.frame

f %>% 
  map_df(~ map(.x, as.character) %>%
          set_names(paste0("COL", seq_along(.x) + 1)), .id = "COL1") %>% 
  retype

данные

f <- list(a = list(1, "false"), b = list(2, "true", "3"))
f1 <- list(a=list(1,"false"),b=list("2","true","3"))   
0 голосов
/ 15 мая 2019

Как насчет другого простого базового решения R.

f <- list(a=list(1,2.5,9.5),b=list("2","-true","3",4))
m = matrix(NA,ncol=max(sapply(f,length)),nrow=length(f))
for(i in 1:nrow(m)) {
  u = unlist(f[[i]])
  m[i,1:length(u)] = u
}
your_data_frame = as.data.frame(m)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...