Попробуйте этот трюк, который (я думаю) является устойчивым к количеству уровней.
Эквивалентно дословному ToothGrowth$dose
, вместо этого программно извлекаются уровни из выбранных group
.
ToothGrowth[[input$group]]
# [1] 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
# [20] 1.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5
# [39] 0.5 0.5 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0 2.0 2.0 2.0 2.0 2.0 2.0
# [58] 2.0 2.0 2.0
Мы хотим увидеть, если $len
больше всех значений ползунков , поэтому команда outer
дает нам матрицу nrow(ToothGrowth)
строк и 3 столбцов (3, потому что dat()
имеет три элемента, три уровня $dose
). Столбец 1 представляет первый ползунок ("0.5"
, если выбрано dose
), столбец 2 представляет второй ползунок ("1"
), а столбец 3 представляет третий ползунок ("2"
).
ToothGrowth$len
# [1] 4.2 11.5 7.3 5.8 6.4 10.0 11.2 11.2 5.2 7.0 16.5 16.5 15.2 17.3 22.5
# [16] 17.3 13.6 14.5 18.8 15.5 23.6 18.5 33.9 25.5 26.4 32.5 26.7 21.5 23.3 29.5
# [31] 15.2 21.5 17.6 9.7 14.5 10.0 8.2 9.4 16.5 9.7 19.7 23.3 23.6 26.4 20.0
# [46] 25.2 25.8 21.2 14.5 27.3 25.5 26.4 22.4 24.5 24.8 30.9 26.4 27.3 29.4 23.0
mapply(`[[`, list(input), dat())
# [1] 30 18 10
head(outer(ToothGrowth$len, mapply(`[[`, list(input), dat()), FUN=`>`))
# [,1] [,2] [,3]
# [1,] FALSE FALSE FALSE
# [2,] FALSE FALSE TRUE
# [3,] FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE
# [5,] FALSE FALSE FALSE
# [6,] FALSE FALSE FALSE
Значение TRUE
означает, что второе значение $len
(11,5) больше, чем значение третьего ползунка (которое, по моим настройкам, равно 10).
mapply
- это уловка для получения значений нескольких input$
элементов. Обычно, если у нас есть имя list
, мы можем использовать один [
для индексации нескольких значений, но это не работает со специальным объектом input$
. Хотя я хотел бы использовать sapply(dat(),
[[, x = input)
, но это не работает (не реализовано в материале shiny
, не удивительно, если кто захочет / должен получить к нему доступ таким образом). Поэтому я использую mapply
, чтобы обойти это.
mapply(`[[`, list(input), dat())
# [1] 30 20 10
Теперь, когда у нас есть матрица 60x3 (из п. 2), нам нужна аналогичная матрица, которая указывает, является ли эта строка $dose
равно уровню столбца. В предыдущем пункте TRUE
обозначает значение 11,5 (строка 2) и $dose
"2"
(столбец 3, ползунок 3). Итак, теперь мы делаем outer
сравнение $dose
с доступными уровнями.
dat()
# [1] "0.5" "1" "2"
head(outer(ToothGrowth[[input$group]], dat(), `==`))
# [,1] [,2] [,3]
# [1,] TRUE FALSE FALSE
# [2,] TRUE FALSE FALSE
# [3,] TRUE FALSE FALSE
# [4,] TRUE FALSE FALSE
# [5,] TRUE FALSE FALSE
# [6,] TRUE FALSE FALSE
Отсюда мы берем две матрицы 60x3 и делаем поэлементное AND:
head(outer(ToothGrowth[[input$group]], dat(), `==`) &
outer(ToothGrowth$len, mapply(`[[`, list(input), dat()), FUN=`>`))
# [,1] [,2] [,3]
# [1,] FALSE FALSE FALSE
# [2,] FALSE FALSE FALSE
# [3,] FALSE FALSE FALSE
# [4,] FALSE FALSE FALSE
# [5,] FALSE FALSE FALSE
# [6,] FALSE FALSE FALSE
tail(outer(ToothGrowth[[input$group]], dat(), `==`) &
outer(ToothGrowth$len, mapply(`[[`, list(input), dat()), FUN=`>`))
# [,1] [,2] [,3]
# [55,] FALSE FALSE TRUE
# [56,] FALSE FALSE TRUE
# [57,] FALSE FALSE TRUE
# [58,] FALSE FALSE TRUE
# [59,] FALSE FALSE TRUE
# [60,] FALSE FALSE TRUE
(Ладно, там не очень интересно, просто подумал, что я покажу голову и хвост, чтобы продемонстрировать совпадение некоторых строк.)
apply
берет матрицу (поэлементное И двух матриц и применяет функцию (any
) к каждой строке (1
, поле, к которому применяется функция).