Как в R вы можете создать перекрестную таблицу из именованного числа на основе его имен? - PullRequest
2 голосов
/ 05 октября 2019

У меня есть числовой вектор с именами после шаблона. Название для каждого элемента состоит из двух частей. Существует фиксированное количество вариаций в первой части и фиксированное количество вариаций во второй части согласно приведенному ниже.

x <- c(2, 4, 3, 7, 6, 9)
names(x) <- c("a.0", "b.0", "c.0", "a.1", "b.1", "c.1")

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

   a   b   c
0  2   4   3
1  7   6   9

Ответы [ 2 ]

8 голосов
/ 05 октября 2019

Вот некоторые возможности. Первые 3 используют только базовую R.

1) tapply Используйте tapply с частями строки и столбца, указанными во втором аргументе.

nms <- names(x)
tapply(x, list(row = sub(".*\\.", "", nms), col = sub("\\..*", "", nms)), c)

, даваяследующая матрица с указанными именами строк и столбцов.

   col
row a b c
  0 2 4 3
  1 7 6 9

2) xtabs Другая возможность заключается в использовании xtabs:

dnms <- read.table(text = names(x), sep = ".", as.is = TRUE, 
  col.names = c("col", "row"))[2:1]
xtabs(x ~ ., dnms)

, задающем этот xtabs /объект таблицы:

   col
row a b c
  0 2 4 3
  1 7 6 9

3) изменить форму

long <- cbind(x, read.table(text = names(x), sep = ".", as.is = TRUE, 
  col.names = c("col", "row")))
r <- reshape(long, dir = "wide", idvar = "row", timevar = "col")[-1]
dimnames(r) <- lapply(long[3:2], unique)

r

с указанием этих данных. кадр:

  a b c
0 2 4 3
1 7 6 9

4)dplyr / tidyr / tibble Используя указанные пакеты, мы можем сформировать следующий конвейер:

library(dplyr)
library(tidyr)
library(tibble)

x %>%
  stack %>%
  separate(ind, c("col", "rowname")) %>%
  pivot_wider(names_from = col, values_from = ".") %>%
  column_to_rownames

с указанием этих data.frame:

  a b c
0 2 4 3
1 7 6 9

Если вы используете старую версиюиз tidyr замените строку pivot_wider на

spread(col, values) %>%

В соответствии с комментарием @db это также будет работать:

x %>% 
  data.frame %>%
  rownames_to_column  %>%
  separate(rowname, c("col", "rowname")) %>%
  pivot_wider(names_from = col, values_from = ".") %>%
  column_to_rownames
1 голос
/ 05 октября 2019
do.call(rbind, split(x, gsub(".*\\.(.*)", "\\1", names(x))))
#  a.0 b.0 c.0
#0   2   4   3
#1   7   6   9
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...