使用 R 将 table 中的三维数据组织成 matrix/array 形式

Organizing three dimensional data from table into matrix/array form using R

我有一个 table 和这个很像

MUNI YEAR ENTE SALE
D101 1995 F001 1000
D101 1995 F002 1200
D101 1995 F003 1300
D101 1996 F001 1000
D101 1996 F003 1250
D101 1996 F004 1300
D101 1997 F001 1000
D101 1998 F002 1400
D101 1998 F003 1500
D102 1995 F001 1000
D102 1995 F003 1200
D102 1995 F006 1300
D102 1996 F001 1050
D102 1996 F002 1320
D102 1996 F003 1250
D102 1996 F006 1350
D102 1996 F002 1320
...

这是销售 table,其中 MUNI 代表市场,ENTE 代表公司。数据由 7 年、1200 个市场和 200 家公司组成。我想将这个 table 重新组织成矩阵形式,这样维度是 (rows = MUNI X YEAR, Cols = ENTE) 并且在每个单元格中都有销售价值,像这样

MUNIxYEAR\ENTE F001 F002 F003 F004 ...
D101x1995 1000 1200 1300 NA ...
D101x1996 1000 NA 1250 1300 ...
...

我不确定如何进行此操作或进行的最佳方式,所以我得到了上述数据组织。我检查了其他帖子,我相信这样做的方法是使用命令 sparseMatrix。但是,当(1)您有多个条件(即行的两个条件)和(2)矩阵的维度是字符串 ID(将它们更改为因子并获取级别)时,我不知道如何使用它?)。

在此先感谢您的帮助和指导。

您可以使用xtabs

例如:

# Set random seed for reproducibility
set.seed(12345)
# Generate 500 rows of random data
my.data = data.frame(MUNI = rep(paste0("D", 101:110), each = 50),
                     YEAR = sample(1990:2000, 500, replace = TRUE),
                     ENTE = sample(paste0("F00", 1:9), 500, replace = T),
                     SALE = sample(1000:2000, 500, replace = T)
                     )

# Create a new column with the string "MUNIxYEAR"
my.data$MUNIxYEAR = paste(my.data$MUNI, my.data$YEAR, sep = "x")

# Call xtabs to get the table!
res <- xtabs(SALE ~ MUNIxYEAR + ENTE, my.data)

输出的第一行:

          ENTE
MUNIxYEAR   F001 F002 F003 F004 F005 F006 F007 F008 F009
  D101x1990 1339    0    0 1693    0 2831 2779    0    0
  D101x1991    0 1407    0 3619    0    0    0 1254    0
  D101x1992    0    0    0    0 1807    0 1766    0 1657
  D101x1993 1174 1154    0    0 1794    0    0 1218    0
  D101x1994    0 1015 6636    0    0    0 2126    0    0
  D101x1995    0    0    0    0    0 3478 3228 1517    0
  D101x1996    0    0 1304    0    0    0 1505    0    0
  D101x1997    0 1077 1481 1802    0 2494    0    0    0
  D101x1998    0    0 1660 5366 1844    0    0 1006    0
  D101x1999    0 1437    0    0    0    0 1844    0 2394
  D101x2000    0    0 1714    0    0    0 1950 1758 1108
  D102x1990 3761    0 3307 1182    0    0    0    0    0
  D102x1991    0    0    0 1539 2716    0 1716    0    0
  D102x1992 1980    0 1056 1458    0    0    0    0 1641
  D102x1993    0    0 1429    0 1784    0 1114    0    0
  D102x1994    0    0    0    0 1377    0 1038 1000    0
  D102x1995    0    0 1088    0    0 1031 4205 1764    0
  D102x1996    0    0    0    0 1658    0 3559    0    0
  D102x1997    0 1048 2453    0    0 1741    0    0    0
  D102x1998 1427 5139    0 1336    0    0 1372    0 1395
  D102x1999    0    0    0 3957    0 1972    0    0    0
  D102x2000    0 3258    0    0    0 3780    0 3299 1360
  D103x1990    0    0    0 1247 1526    0    0    0 1234
  D103x1991    0 1919    0    0    0    0    0 1704    0
  D103x1992    0 1489    0    0 4428    0 1371    0    0
  D103x1993    0 1477    0    0    0    0 1319    0 1211
  D103x1994    0 2649    0    0 1488    0    0    0    0

xtabs 函数可以帮助将数据重新格式化为 3 维数组,然后 ftable 函数可以将其展平为二维 table。

其他选项是 reshape2 或 plyr 包(可能还有其他包)。

有很多方法和包可以做到这一点。我正在使用 "tidyr" 包方法:

library(tidyr)

df = data.frame(MUNI = rep(paste0("D10", c(1,1,2,2,3,4)), each = 2),
                YEAR = rep(1999:2000,3),
                ENTE = paste0("F00", c(1,2,3,3,4,5)),
                SALE = sample(1000:2000, 6, replace = T))

df

#    MUNI YEAR ENTE SALE
# 1  D101 1999 F001 1670
# 2  D101 2000 F002 1420
# 3  D101 1999 F003 1985
# 4  D101 2000 F003 1914
# 5  D102 1999 F004 1727
# 6  D102 2000 F005 1195
# 7  D102 1999 F001 1670
# 8  D102 2000 F002 1420
# 9  D103 1999 F003 1985
# 10 D103 2000 F003 1914
# 11 D104 1999 F004 1727
# 12 D104 2000 F005 1195


spread(df,ENTE,SALE, fill=0)    # in case you decide to have each column separately for querying or further grouping in the future

#   MUNI YEAR F001 F002 F003 F004 F005
# 1 D101 1999 1716    0 1516    0    0
# 2 D101 2000    0 1917 1155    0    0
# 3 D102 1999 1716    0    0 1259    0
# 4 D102 2000    0 1917    0    0 1291
# 5 D103 1999    0    0 1516    0    0
# 6 D103 2000    0    0 1155    0    0
# 7 D104 1999    0    0    0 1259    0
# 8 D104 2000    0    0    0    0 1291


df2 = spread(df,ENTE,SALE, fill=0)
unite(df2, "MUNIxYEAR", MUNI,YEAR, sep = " x ")   # if you want to combine columns

#     MUNIxYEAR F001 F002 F003 F004 F005
# 1 D101 x 1999 1716    0 1516    0    0
# 2 D101 x 2000    0 1917 1155    0    0
# 3 D102 x 1999 1716    0    0 1259    0
# 4 D102 x 2000    0 1917    0    0 1291
# 5 D103 x 1999    0    0 1516    0    0
# 6 D103 x 2000    0    0 1155    0    0
# 7 D104 x 1999    0    0    0 1259    0
# 8 D104 x 2000    0    0    0    0 1291