Как разбить список векторов на столбцы или матрицу?

У меня есть список векторов, которые принимают эту форму:

> g
[[1]]
 [1] "L"  "14" "L"  "39" "L"  "61" "B"  "0"  "L"  "15" "L"  "59" "W"  "64"

[[2]]
[1] "L"  "62" "D"  "31" "L"  "10" "L"  "30" "B"  "0"  "D"  "45" "L"  "43"

[[3]]
 [1] "H"  "0"  "L"  "11" "L"  "35" "W"  "45" "H"  "0"  "L"  "40" "L"  "42"

Моя цель - использовать mapply на этой структуре и превратить каждый из 14 столбцов в вектор. Первый столбец будет:

[[1]]
[1] "L"

[[2]]
[1] "L"

[[3]]
[1] "H"

И второй столбец будет:

[[1]]
[1] "14"

[[2]]
[1] "62"

[[3]]
[1] "0"

и так далее. Я подозреваю, что структура будет матрица (?), Но я не уверен. Я использовал много lapply а также stringr"s str_extract_all с регулярным выражением, чтобы получить эту точку, но я не уверен, как поступить. Я подозреваю, что функция будет использовать шаблон как: "[A-Z]{1}" для текста и "[:digit:]{1}" и я знаю что mapply может вернуть матрицу, но я не знаю, с чего начать.

2 ответа

Решение

Вот решение с использованием mapply

g <- list()
g[[1]] <- c("L",  "14", "L",  "39", "L",  "61", "B",  "0",  "L",  "15", "L",  "59", "W",  "64")
g[[2]] <- c("L",  "62", "D",  "31", "L",  "10", "L",  "30", "B",  "0",  "D",  "45", "L",  "43")
g[[3]] <- c("H",  "0",  "L",  "11", "L",  "35", "W",  "45", "H",  "0",  "L",  "40", "L",  "42")

Рассмотрим простой случай, когда вы хотите извлечь первый элемент в каждом элементе списка, вы можете использовать lapply:

lapply(g, function (x) x[1])

Теперь мы можем использовать mapply для итерации:

lengths(g) # returns length of each element in the list
g2 <- mapply(function(y) lapply(g, function (x) x[y]), 1:lengths(g)[1])
g2

#      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
# [1,] "L"  "14" "L"  "39" "L"  "61" "B"  "0"  "L"  "15"  "L"   "59"  "W"   "64" 
# [2,] "L"  "62" "D"  "31" "L"  "10" "L"  "30" "B"  "0"   "D"   "45"  "L"   "43" 
# [3,] "H"  "0"  "L"  "11" "L"  "35" "W"  "45" "H"  "0"   "L"   "40"  "L"   "42" 

g2[,1]
# [[1]]
# [1] "L"

# [[2]]
# [1] "L"

# [[3]]
# [1] "H"

unlist(g2[,1])
# [1] "L" "L" "H"

Как альтернатива do.call(rbind, g), мы можем использовать тот факт, что data.frame на самом деле представляет собой список векторов, где все векторы имеют одинаковую длину. Итак, данная структура gможет быть преобразован в data.frame, который затем транспонируется с получением матрицы по запросу.

Воспроизведите данные:

g <- list(
  c("L",  "14", "L",  "39", "L",  "61", "B",  "0",  "L",  "15", "L",  "59", "W",  "64"),
  c("L",  "62", "D",  "31", "L",  "10", "L",  "30", "B",  "0",  "D",  "45", "L",  "43"),
  c("H",  "0",  "L",  "11", "L",  "35", "W",  "45", "H",  "0",  "L",  "40", "L",  "42")
)

Transform:

m <- t(as.data.frame(g))
dimnames(m) <- NULL   # remove deafault row names
m
#     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
#[1,] "L"  "14" "L"  "39" "L"  "61" "B"  "0"  "L"  "15"  "L"   "59"  "W"   "64" 
#[2,] "L"  "62" "D"  "31" "L"  "10" "L"  "30" "B"  "0"   "D"   "45"  "L"   "43" 
#[3,] "H"  "0"  "L"  "11" "L"  "35" "W"  "45" "H"  "0"   "L"   "40"  "L"   "42"

Доступ к столбцам:

m[, 1]
#[1] "L" "L" "H"
Другие вопросы по тегам