【问题标题】:Creating a 3D Matrix in R based on the presence of some specific values in groups of data in a data set根据数据集中的数据组中某些特定值的存在,在 R 中创建 3D 矩阵
【发布时间】:2019-03-24 05:32:45
【问题描述】:

我正在使用 R 中的数据集,假设 mtcars:

                   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8 360.0 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360        14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 240D         24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Merc 230          22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Merc 280          19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4

现在我想为am: (0 = automatic, 1 = manual) 的每种传输类型创建一个矩阵,显示变量carb 的任何级别是否存在于变量cyl 的任何级别中。换一种说法,如果cyl 可以有4 , 6 and 81, 2, 3, 4, 6 and 8 的值是变量carb 的可能值,那么我想要一个3x6 矩阵用于每种传输类型,如果@ 的每个组合,其元素为1 987654331@ 存在于我们的数据中,而0 则存在于我们的数据中。因此,生成的矩阵应该是维度2x3x6。例如:

(这里的这些矩阵仅用于说明目的,它们的元素是我自己任意选择的,以便更好地解释我期望什么样的输出)

for am == 0
  1 2 3 4 6 8
4 0 0 1 0 1 0
6 1 0 0 1 1 1
8 0 1 0 0 1 0

for am == 1
  1 2 3 4 6 8
4 1 0 0 0 1 0
6 0 1 0 1 0 0
8 0 1 1 0 1 1

我知道dplyr 对于此类数据操作非常方便,但我不知道在这种情况下如何使用它,我想根据另一个数据框中的变量组创建矩阵?!

非常感谢任何帮助。

【问题讨论】:

  • 嗨!请分享一个预期的表格输出,它会有所帮助。

标签: r matrix data-manipulation


【解决方案1】:

这是一种不太优雅的蛮力方法:

mtcars

res <- with(mtcars, array(
    data = 0L,
    dim = c(
        length(unique(cyl )),
        length(unique(carb)),
        length(unique(am  ))
    ),
    dimnames = list(
        paste("cyl",  sort(unique(cyl )), sep = "_"),
        paste("carb", sort(unique(carb)), sep = "_"),
        paste("am",   sort(unique(am  )), sep = "_")
    )
))

for(x in seq_len(dim(res)[1])) {
    for(y in seq_len(dim(res)[2])) {
        for(z in seq_len(dim(res)[3])) {
            if (any(
                mtcars$cyl  == readr::parse_number(dimnames(res)[[1]][x]) &
                mtcars$carb == readr::parse_number(dimnames(res)[[2]][y]) &
                mtcars$am   == readr::parse_number(dimnames(res)[[3]][z])
            )) {
                res[x, y, z] <- 1L
            }
        }
    }
}

res

【讨论】:

  • 非常感谢,尽管我不同意您的解决方案的优雅性!一个问题,any() 在 if 语句中做了什么?
  • any() 检查它检查的逻辑向量的任何值是否为 TRUE。
【解决方案2】:

我们可以split'am'列的数据子集得到table

# convert the 'carb' column to `factor` with `levels` specified
# inorder to get all the combinations
mtcars$carb <- factor(mtcars$carb, levels = sort(unique(mtcars$carb)))
lapply(split(mtcars[c("cyl", "carb")], mtcars$am), function(x) +(table(x) > 0))

【讨论】:

  • 感谢您的出色解决方案,我从中学到了很多,特别是您用于将真/假矩阵转换为 1/0 的技巧!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多