【问题标题】:creating a square matrix from a data frame [duplicate]从数据框创建方阵[重复]
【发布时间】:2018-03-15 16:31:30
【问题描述】:

我无法从我的 data.frame 中制作方阵。 现在我的数据看起来像这样:

  var1 var2 value
    A    B     4
    C    D     5 
    D    A     2
    B    D     1

我正在尝试将 data.frame 转换为如下所示的矩阵:

    A    B    C   D
  A 0    4    0   2
  B 4    0    0   1
  C 0    0    0   5
  D 2    1    5   0

我尝试了 R 中可用的不同包中的许多功能,但仍然找不到解决方案。

【问题讨论】:

  • 请贴出您尝试过的许多功能以及为什么不起作用
  • xtabs(value~var1+var2, df) ?
  • @Sotos 这将错过列C
  • 感谢您帮助我。 @PoGibas 我试过这个:comatrix <- data.frame(var1 = data3$u1.var1, scores = data3$value, var2= factor(data3$var2,levels=unique(data3$var2))) acast(comatrix, formula = var1 ~ var2, fill = 0, value.var ="scores", fun.aggregate =sum, drop = FALSE) 通过这段代码,我得到了一个矩阵,但不是正方形

标签: r matrix dataframe


【解决方案1】:

这是一个在字符向量上使用矩阵索引的基本 R 方法。

## set up storage matrix
# get names for row and columns
nameVals <- sort(unique(unlist(dat[1:2])))
# construct 0 matrix of correct dimensions with row and column names
myMat <- matrix(0, length(nameVals), length(nameVals), dimnames = list(nameVals, nameVals))

# fill in the matrix with matrix indexing on row and column names
myMat[as.matrix(dat[c("var1", "var2")])] <- dat[["value"]]

返回

myMat
  A B C D
A 0 4 0 0
B 0 0 0 1
C 0 0 0 5
D 2 0 0 0

有关这种强大的索引形式如何工作的详细信息,请参阅帮助文件?"["矩阵和数组部分。特别是,本节的第四段讨论了这种索引形式。

请注意,我假设前两个变量是字符向量而不是因子。这使它更容易一些,因为我不必使用as.character 来强制它们。

要将结果转换为 data.frame,只需将上述代码包装在 as.data.frame 函数中即可。

数据

dat <- 
structure(list(var1 = c("A", "C", "D", "B"), var2 = c("B", "D", 
"A", "D"), value = c(4L, 5L, 2L, 1L)), .Names = c("var1", "var2", 
"value"), class = "data.frame", row.names = c(NA, -4L))

【讨论】:

    【解决方案2】:

    如果我们将所有字符列factors 设置为级别“A”、“B”、“C”、“D”,那么我们可以使用xtabs 而不会删除任何列。

    很遗憾,生成的矩阵不是对称的。

    library('tidyverse')
    
    df <- tribble(
      ~var1, ~var2, ~value,
        'A',   'B',      4,
        'C',   'D',      5,
        'D',   'A',      2,
        'B',   'D',      1
    )
    
    df %>%
      mutate_if(is.character, factor, levels=c('A', 'B', 'C', 'D')) %>%
      xtabs(value ~ var1 + var2, ., drop.unused.levels = F)
    #     var2
    # var1 A B C D
    #    A 0 4 0 0
    #    B 0 0 0 1
    #    C 0 0 0 5
    #    D 2 0 0 0
    

    为了使其对称,我只是将其转置添加到自身。不过,这感觉有点像 hack。

    df %>%
      mutate_if(is.character, factor, levels=c('A', 'B', 'C', 'D')) %>%
      xtabs(value ~ var1 + var2, ., drop.unused.levels = F) %>%
      '+'(., t(.))
    #     var2
    # var1 A B C D
    #    A 0 4 0 2
    #    B 4 0 0 1
    #    C 0 0 0 5
    #    D 2 1 5 0
    

    【讨论】:

    • “不过,这感觉有点像 hack”——这可以说是 R 中许多好的解决方案。+1
    • 感谢您的详细回复@Paul。但实际上,我仍然有一个问题,因为我将变量存储在数据框中。 df &lt;- tribble(~var1,~var2,~score,data3$var1,data3$var2,data3$score) df %&gt;% mutate_if(is.character, factor, levels=c('data3$var1','data3$var2')) %&gt;% xtabs(score ~ var1 + var2,., drop.unused.levels = F) %&gt;% '+'(., t(.))
    • 您使用tribble 的方式将产生列表列。你可以使用data3 %&gt;% mutate_if(is.character, factor, levels=c('A', 'B', 'C', 'D')) %&gt;% xtabs(score ~ var1 + var2, ., drop.unused.levels = F) %&gt;% '+'(., t(.))
    猜你喜欢
    • 2018-02-11
    • 2020-07-02
    • 1970-01-01
    • 2013-03-30
    • 1970-01-01
    • 2018-02-14
    • 1970-01-01
    • 2014-11-30
    相关资源
    最近更新 更多