group_by并创建一个稀疏矩阵

时间:2019-01-29 22:01:13

标签: r

我正在尝试将一些数据转换为稀疏矩阵。看起来像:

       col1 col2        
  [1,] "5"  "LQEMF0072E"
  [2,] "3"  "KKZZY5914F"
  [3,] "4"  "UTDLY0947T"
  [4,] "4"  "QKGTX6135E"
  [5,] "1"  "FVKVY7432D"
  [6,] "1"  "RXDLC3097S"
  [7,] "1"  "OQZKN5913X"
  [8,] "2"  "XNTHW9334J"
  [9,] "5"  "AHFFZ7845R"

所以我有小组:

1 = group1
2 = group2
3 = group3
4 = group4
5 = group5

我正在尝试创建一个稀疏矩阵,该矩阵本质上将是100列宽(观察/单词数)和5行深(组数)。

group1 0 0 0 0 0 1 0 0 0 0 
group2 0 0 1 0 0 0 0 0 0 0
group3 0 0 0 0 0 0 0 0 0 1
etc.

rsample包中的以下内容对我不起作用。

sparsedat <- dat %>%
  group_by(as.numeric(col1)) %>%
  cast_sparse(col2)

数据:

names <- c("name1", "name2", "name3", "name4")
    col1 <- sample(1:5, 100, replace = TRUE)

    myFun <- function(n = 5000) {
      a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
      paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
    }
    col2 <- myFun(100)
    col2

    dat <- cbind(col1, col2)
    dat

编辑:

这是我的数据输出,其中“ col1”是字符向量-group1,group2 ... group 5:

Warning message: In storage.mode(from) <- "double" : NAs introduced by coercion

[1,] NA 11 . 21 .  . 16 9 3 3 1 . . 1  5 . 2 1 2 . . 3 . 3 2 2 1 13 . . . . . . .
[2,] NA  3 6  . .  .  . . . . . . . .  1 . . . 1 2 . 4 2 . 3 . .  . . . . . . . .
[3,] NA  . . 20 1 12  2 4 1 . . 3 5 .  . 2 1 . . . 2 . . . . . .  . . . . . . . .
[4,] NA  . .  9 .  .  1 1 2 . 2 . . . 27 2 . . . . . 2 . . . . .  . 2 1 1 3 1 3 3

[1,] ......
[2,] ......
[3,] ......
[4,] ......

NA是通过将一列字符输入矩阵来产生的。我是否必须将它们分解,然后重新添加字符串?我想保留字符串,因为它们有助于识别行/组的ID。

编辑2:以下内容似乎复制了我的NA问题:

names <- c("name1", "name2", "name3", "name4")
col1 <- sample(1:5, 100, replace = TRUE)

col1 <- paste("group", col1)

myFun <- function(n = 5000) {
  a <- do.call(paste0, replicate(5, sample(LETTERS, n, TRUE), FALSE))
  paste0(a, sprintf("%04d", sample(9999, n, TRUE)), sample(LETTERS, n, TRUE))
}
col2 <- myFun(100)
col2


dat <- cbind(col1, col2)
dat

dat_sparse <- dat %>% 
  as_tibble() %>%
  count(col1, col2) %>%
  spread(col2, n, fill = 0) %>%
  as.matrix() %>%
  Matrix(., sparse = TRUE)

tail(dat_sparse)

1 个答案:

答案 0 :(得分:1)

我们可以使用countspread。这样就产生了data.frame,您可以轻松地将其转换回1和0的矩阵。

library(tidyverse)

dat %>% 
    as_data_frame() %>%
    count(col1, col2) %>%
    spread(col2, n, fill = 0)

#   col1  AAPMN9343Q AKGAW7022W AMUQA3013Z AYQOG3513J BARTE6056J ...
#   <chr>      <dbl>      <dbl>      <dbl>      <dbl>      <dbl> ...
# 1 1              0          0          0          0          0 ...
# 2 2              1          0          1          1          0 ...
# 3 3              0          0          0          0          0 ...
# 4 4              0          0          0          0          0 ...
# 5 5              0          1          0          0          1 ...

为回答您的后续问题,您首先需要创建不包含第一列的矩阵(这避免了强制使用NA)。然后,您可以向该矩阵添加行名。

dat_matrix <- as.matrix(dat[,-1]) # exclude first column of character
rownames(dat_matrix) <- dat %>% pull(col1) # add rownames
sparse_dat_matrix <- Matrix::Matrix(dat_matrix, sparse = TRUE) # make sparse

#         AAWYL0013E ABPGV8707B AEMJZ9793B AQTCL9157H ARBYM6583T
# group 1          .          .          .          1          .
# group 2          .          .          1          .          .
# group 3          .          1          .          .          .
# group 4          .          .          .          .          1
# group 5          1          .          .          .          .