#r #dataframe #matrix #dplyr
#r #фрейм данных #матрица #dplyr
Вопрос:
Проблема
У меня есть простая матрица:
library(tidyverse)
m <- matrix(seq(1,25), nrow = 5, ncol =5)
m
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 1 6 11 16 21
#> [2,] 2 7 12 17 22
#> [3,] 3 8 13 18 23
#> [4,] 4 9 14 19 24
#> [5,] 5 10 15 20 25
Эта матрица содержит значения, которые я хотел бы сохранить в качестве третьего столбца в dataframe, который содержит все комбинации индексов:
library(tidyverse)
df <- expand_grid(V1 = 1:5, V2 = 1:5)
Попытка
df <- df %>%
mutate(value = m[V1, V2])
При этом сохраняется целая матрица для каждого поля фрейма данных, а не только соответствующее значение.
Ожидаемый результат
#> # A tibble: 25 x 3
#> V1 V2 value
#> <int> <int> <int>
#> 1 1 1 1
#> 2 1 2 6
#> 3 1 3 11
#> 4 1 4 16
#> and so on...
Вопрос
Как мне это сделать с помощью mutate в R?
Примечание
Я знаю, что в этом случае я мог бы просто изменить данные. Однако я хотел бы применить тот же подход к многомерному массиву (т. Е. , mutate(value = m[V1,V2,V3])
, Который содержит только подмножество комбинаций индексов. Надеюсь, вопрос ясен, в противном случае: дайте мне знать :)!
Ответ №1:
Использовать cbind
:
df %>%
mutate(value = m[cbind(V1, V2)])
# # A tibble: 25 x 3
# V1 V2 value
# <int> <int> <int>
# 1 1 1 1
# 2 1 2 6
# 3 1 3 11
# 4 1 4 16
# 5 1 5 21
# 6 2 1 2
# 7 2 2 7
# 8 2 3 12
# 9 2 4 17
# 10 2 5 22
# # ... with 15 more rows
И он работает с n-мерными массивами (a matrix
— это 2-тусклый массив, так что это естественное расширение этого):
m <- array(seq_len(5^3), dim=c(5, 5, 5))
expand_grid(V1 = 1:2, V2 = 2:3, V3 = 3:4) %>%
mutate(value = m[cbind(V1, V2, V3)])
# # A tibble: 8 x 4
# V1 V2 V3 value
# <int> <int> <int> <int>
# 1 1 2 3 56
# 2 1 2 4 81
# 3 1 3 3 61
# 4 1 3 4 86
# 5 2 2 3 57
# 6 2 2 4 82
# 7 2 3 3 62
# 8 2 3 4 87
Комментарий к обсуждению для использования rowwise
:
rowwise
полезна в очень специфических ситуациях и несет в себе немалое снижение производительности. Ее полезность заключается в том, что нужные вам функции не векторизуются, вместо этого требуется один ввод (из нуля или более моделей) за раз. Часто я считаю, что лучше явно выполнять вычисления такого типа, используя sapply
/ lapply
/ vapply
/ mapply
(базовый R) или purrr::map*
варианты. Хотя эффект относительно одинаков (вычисления выполняются поэлементно), для меня он немного понятнее и позволяет выполнять вычисления не по строкам в одном и том же mutate
(и исключает случайное забывание в ungroup
строковом фрейме).