如何在R中如何基于命名的num名称从其创建交叉表?

eri*_*son 2 r

我有一个数字矢量,其名称遵循模式。每个元素的名称由两部分组成。根据以下内容,在第一部分上有固定数量的变体,在第二部分上有固定数量的变体。

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

由此,我想创建并打印一个表格,其中名称的第一部分是行,第二部分是下面的列。

   a   b   c
0  2   4   3
1  7   6   9
Run Code Online (Sandbox Code Playgroud)

G. *_*eck 8

这里有一些可能性。前3个仅使用基数R。

1)tapply使用tapply与第二自变量指定的行和列的部分。

nms <- names(x)
tapply(x, list(row = sub(".*\\.", "", nms), col = sub("\\..*", "", nms)), c)
Run Code Online (Sandbox Code Playgroud)

给出具有指示的行和列名称的以下矩阵。

   col
row a b c
  0 2 4 3
  1 7 6 9
Run Code Online (Sandbox Code Playgroud)

2)xtabs的另一种可能性是使用xtabs

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

给这个xtabs / table对象:

   col
row a b c
  0 2 4 3
  1 7 6 9
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

给这个data.frame:

  a b c
0 2 4 3
1 7 6 9
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

给这个data.frame:

  a b c
0 2 4 3
1 7 6 9
Run Code Online (Sandbox Code Playgroud)

如果您使用的是Tidyr的旧版本,请pivot_wider

spread(col, values) %>%
Run Code Online (Sandbox Code Playgroud)

根据@db注释,这也可以工作:

x %>% 
  data.frame %>%
  rownames_to_column  %>%
  separate(rowname, c("col", "rowname")) %>%
  pivot_wider(names_from = col, values_from = ".") %>%
  column_to_rownames
Run Code Online (Sandbox Code Playgroud)