R - сдвинуть несколько строк и соответственно расширить матрицу - PullRequest
1 голос
/ 14 мая 2019

Это связано с вопросом R - преобразование восходящих диагоналей в строки :

Мне дана матрица, фрейм данных или таблица данных.Я хотел бы создать новую матрицу, сдвигая строку i на (i-1) ячеек, но не обрезая строки, т.е. добавляются дополнительные столбцы (дополнительные ячейки установлены в NA).

В качестве примера предположим, что мне дана следующая матрица

mat <-matrix (seq (1: 100), nrow = 20, byrow = TRUE) </p>

 > structure(mat)
     V1 V2 V3 V4  V5
  1:  1  2  3  4   5
  2:  6  7  8  9  10
  3: 11 12 13 14  15
  4: 16 17 18 19  20
  5: 21 22 23 24  25
  6: 26 27 28 29  30
  7: 31 32 33 34  35
  8: 36 37 38 39  40
  9: 41 42 43 44  45
 10: 46 47 48 49  50
 11: 51 52 53 54  55
 12: 56 57 58 59  60
 13: 61 62 63 64  65
 14: 66 67 68 69  70
 15: 71 72 73 74  75
 16: 76 77 78 79  80
 17: 81 82 83 84  85
 18: 86 87 88 89  90
 19: 91 92 93 94  95
 20: 96 97 98 99 100

> dput(mat)
structure(list(V1 = c(1L, 6L, 11L, 16L, 21L, 26L, 31L, 36L, 41L, 
46L, 51L, 56L, 61L, 66L, 71L, 76L, 81L, 86L, 91L, 96L), V2 = c(2L, 
7L, 12L, 17L, 22L, 27L, 32L, 37L, 42L, 47L, 52L, 57L, 62L, 67L, 
72L, 77L, 82L, 87L, 92L, 97L), V3 = c(3L, 8L, 13L, 18L, 23L, 
28L, 33L, 38L, 43L, 48L, 53L, 58L, 63L, 68L, 73L, 78L, 83L, 88L, 
93L, 98L), V4 = c(4L, 9L, 14L, 19L, 24L, 29L, 34L, 39L, 44L, 
49L, 54L, 59L, 64L, 69L, 74L, 79L, 84L, 89L, 94L, 99L), V5 = c(5L, 
10L, 15L, 20L, 25L, 30L, 35L, 40L, 45L, 50L, 55L, 60L, 65L, 70L, 
75L, 80L, 85L, 90L, 95L, 100L)), row.names = c(NA, -20L), class = c("data.table","data.frame"))

Желаемый результат выглядит следующим образом:

> dput(res)
structure(c(1L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 2L, 6L, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 3L, 7L, 11L, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
4L, 8L, 12L, 16L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, 5L, 9L, 13L, 17L, 21L, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 10L, 14L, 18L, 22L, 
26L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, 15L, 19L, 23L, 27L, 31L, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, 20L, 24L, 28L, 32L, 36L, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
25L, 29L, 33L, 37L, 41L, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 30L, 34L, 38L, 42L, 46L, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 35L, 
39L, 43L, 47L, 51L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, 40L, 44L, 48L, 52L, 56L, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 45L, 49L, 53L, 
57L, 61L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, 50L, 54L, 58L, 62L, 66L, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 55L, 59L, 63L, 67L, 71L, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
60L, 64L, 68L, 72L, 76L, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, 65L, 69L, 73L, 77L, 81L, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 70L, 
74L, 78L, 82L, 86L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, 75L, 79L, 83L, 87L, 91L, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 80L, 84L, 88L, 
92L, 96L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, 85L, 89L, 93L, 97L, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, 90L, 94L, 98L, NA, NA, NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 95L, 
99L, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, NA, NA, 100L), .Dim = c(20L, 24L))

Есть ли простой и короткий способ сделать это?

Ответы [ 4 ]

2 голосов
/ 14 мая 2019

Опция будет

out <- matrix(NA, nrow(mat)+4, nrow(mat)+4)
for(i in seq_len(nrow(out))) out[i, (i:(i+4))] <- unlist(mat[i])
out[1:nrow(mat), ]
0 голосов
/ 14 мая 2019

Вы можете создать матрицу с желаемыми размерами, а затем вставить mat в нужное место, используя row и col, но для ее заполнения по строкам требуется много транспонирования.

res <- matrix(NA, nrow(mat), nrow(mat) + ncol(mat) - 1)
res <- t(res)
i.diag <- row(res) - col(res)
res[i.diag >= 0 & i.diag <= 4] <- t(mat)
res <- t(res)

Выход

# res1 is the result in the question
all.equal(res1, res)
# [1] TRUE

res
#       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14] [,15]
#  [1,]    1    2    3    4    5   NA   NA   NA   NA    NA    NA    NA    NA    NA    NA
#  [2,]   NA    6    7    8    9   10   NA   NA   NA    NA    NA    NA    NA    NA    NA
#  [3,]   NA   NA   11   12   13   14   15   NA   NA    NA    NA    NA    NA    NA    NA
#  [4,]   NA   NA   NA   16   17   18   19   20   NA    NA    NA    NA    NA    NA    NA
#  [5,]   NA   NA   NA   NA   21   22   23   24   25    NA    NA    NA    NA    NA    NA
#  [6,]   NA   NA   NA   NA   NA   26   27   28   29    30    NA    NA    NA    NA    NA
#  [7,]   NA   NA   NA   NA   NA   NA   31   32   33    34    35    NA    NA    NA    NA
#  [8,]   NA   NA   NA   NA   NA   NA   NA   36   37    38    39    40    NA    NA    NA
#  [9,]   NA   NA   NA   NA   NA   NA   NA   NA   41    42    43    44    45    NA    NA
# [10,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    46    47    48    49    50    NA
# [11,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    51    52    53    54    55
# [12,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    56    57    58    59
# [13,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    61    62    63
# [14,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    66    67
# [15,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    NA    71
# [16,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    NA    NA
# [17,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    NA    NA
# [18,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    NA    NA
# [19,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    NA    NA
# [20,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA    NA    NA
#       [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
#  [1,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
#  [2,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
#  [3,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
#  [4,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
#  [5,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
#  [6,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
#  [7,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
#  [8,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
#  [9,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
# [10,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
# [11,]    NA    NA    NA    NA    NA    NA    NA    NA    NA
# [12,]    60    NA    NA    NA    NA    NA    NA    NA    NA
# [13,]    64    65    NA    NA    NA    NA    NA    NA    NA
# [14,]    68    69    70    NA    NA    NA    NA    NA    NA
# [15,]    72    73    74    75    NA    NA    NA    NA    NA
# [16,]    76    77    78    79    80    NA    NA    NA    NA
# [17,]    NA    81    82    83    84    85    NA    NA    NA
# [18,]    NA    NA    86    87    88    89    90    NA    NA
# [19,]    NA    NA    NA    91    92    93    94    95    NA
# [20,]    NA    NA    NA    NA    96    97    98    99   100
0 голосов
/ 14 мая 2019

Если вы используете библиотеку slam, вы можете ввести 3 вектора, один для соответствующих строк, один для столбцов, один для значений вашей матрицы.Плюс, это в разреженном формате:

mat<-matrix(seq(1:100),nrow=20, byrow = TRUE)

my_values <- as.numeric(stack(as.data.frame(t(mat)), select = names(as.data.frame(t(mat))))[, 1])
my_rows <- rep(seq_len(nrow(mat)), each = ncol(mat))
my_cols <- rep(seq_len(ncol(mat)), times = nrow(mat)) + my_rows - 1

library(slam)

want <- simple_triplet_matrix(i = my_rows, j = my_cols, v = my_values)
as.matrix(want) # or just leave as simple_triplet_matrix
0 голосов
/ 14 мая 2019
mat<-matrix(seq(1:100),nrow=20, byrow = TRUE)
extra_cols <- matrix(
  rep(NA_real_,nrow(mat)*(nrow(mat)-1)),
  nrow(mat),(nrow(mat)-1)
)
mat <- cbind(mat,extra_cols) #Pad with NA's

t(sapply(1:nrow(mat),function(i){ dplyr::lag(mat[i,],i-1)})) # Lag and transpose
#>       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13]
#>  [1,]    1    2    3    4    5   NA   NA   NA   NA    NA    NA    NA    NA
#>  [2,]   NA    6    7    8    9   10   NA   NA   NA    NA    NA    NA    NA
#>  [3,]   NA   NA   11   12   13   14   15   NA   NA    NA    NA    NA    NA
#>  [4,]   NA   NA   NA   16   17   18   19   20   NA    NA    NA    NA    NA
#>  [5,]   NA   NA   NA   NA   21   22   23   24   25    NA    NA    NA    NA
#>  [6,]   NA   NA   NA   NA   NA   26   27   28   29    30    NA    NA    NA
#>  [7,]   NA   NA   NA   NA   NA   NA   31   32   33    34    35    NA    NA
#>  [8,]   NA   NA   NA   NA   NA   NA   NA   36   37    38    39    40    NA
#>  [9,]   NA   NA   NA   NA   NA   NA   NA   NA   41    42    43    44    45
#> [10,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    46    47    48    49
#> [11,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    51    52    53
#> [12,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    56    57
#> [13,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    61
#> [14,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA
#> [15,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA
#> [16,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA
#> [17,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA
#> [18,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA
#> [19,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA
#> [20,]   NA   NA   NA   NA   NA   NA   NA   NA   NA    NA    NA    NA    NA
#>       [,14] [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24]
#>  [1,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#>  [2,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#>  [3,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#>  [4,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#>  [5,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#>  [6,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#>  [7,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#>  [8,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#>  [9,]    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#> [10,]    50    NA    NA    NA    NA    NA    NA    NA    NA    NA    NA
#> [11,]    54    55    NA    NA    NA    NA    NA    NA    NA    NA    NA
#> [12,]    58    59    60    NA    NA    NA    NA    NA    NA    NA    NA
#> [13,]    62    63    64    65    NA    NA    NA    NA    NA    NA    NA
#> [14,]    66    67    68    69    70    NA    NA    NA    NA    NA    NA
#> [15,]    NA    71    72    73    74    75    NA    NA    NA    NA    NA
#> [16,]    NA    NA    76    77    78    79    80    NA    NA    NA    NA
#> [17,]    NA    NA    NA    81    82    83    84    85    NA    NA    NA
#> [18,]    NA    NA    NA    NA    86    87    88    89    90    NA    NA
#> [19,]    NA    NA    NA    NA    NA    91    92    93    94    95    NA
#> [20,]    NA    NA    NA    NA    NA    NA    96    97    98    99   100

Создано в 2019-05-14 пакетом представ (v0.2.1)

...