Использование ifelse или цикла if в функции panel в Lattice не работает с panel.xyplot

#r #lattice

#r #решетка

Вопрос:

Я пытаюсь нарисовать график lattice , на котором цвета точек и форма изменяются на основе переменных в данных. Это отлично работает, когда я устанавливаю значения col and pch самостоятельно и не помещаю panel.xyplot в ifelse оператор:

 #Setup
library(cluster)
library(lattice)

xyplot(V8 ~ V7,
       data = flower,
       V8_var = flower$V8,
       panel = function(x, y, ..., V8_var, subscripts) {
         
         col <- ifelse(V8_var[subscripts] < 50,
                       'blue',
                       'orange')
         
         pch <- ifelse(V8_var[subscripts] < 50,
                       2,
                       6)
         
           panel.xyplot(x,y,type='p',
                        col = col,
                        pch = pch)
         
       })
 

quot;Правильноеquot; изображение, нарисованное двумя разными цветами и двумя разными формами

Однако это не работает, когда я использую panel.xyplot в ifelse if цикле or:

 xyplot(V8 ~ V7,
       data = flower,
       V8_var = flower$V8,
       panel = function(x, y, ..., V8_var, subscripts) {
         
         col <- ifelse(V8_var[subscripts] < 50,
                       'blue',
                       'orange')
         ifelse(
           V8_var[subscripts] < 50,
           panel.xyplot(x,y,type='p',
                        col = col,
                        pch = 2),
           panel.xyplot(x,y,type='p',
                        col = col,
                        pch = 6)
         )
         
       })
 

График с двумя цветами точек, но только с одним pch, хотя функция panel имела оператор ifelse, который вызывал panel.xyplot с другим значением pch в зависимости от значения переменной V8. Также выдает сообщение об ошибке: quot;Ошибка при замене пакета 1 имеет нулевую длинуquot;.

 xyplot(V8 ~ V7,
       data = flower,
       V8_var = flower$V8,
       panel = function(x, y, ..., V8_var, subscripts) {
         
         col <- ifelse(V8_var[subscripts] < 50,
                       'blue',
                       'orange')
         
         if(V8_var[subscripts] < 50){
           panel.xyplot(x,y,type='p',
                        col = col,
                        pch = 2)
           } else {
           panel.xyplot(x,y,type='p',
                        col = col,
                        pch = 6)
           }
       }) 
 

График с двумя цветами точек, но только с одним pch, хотя функция panel имела цикл if, который вызывал panel.xyplot с другим значением pch в зависимости от значения переменной V8.

Использование if инструкции также выдает предупреждение:

 Warning message:
In if (V8_var[subscripts] < 50) { :
  the condition has length > 1 and only the first element will be used
 

Способ обойти это — получить значения переменных через if ifelse оператор or, а затем подключить их к panel.xyplot любым if операторам, но я не понимаю, почему ifelse оператор не работает так, как я ожидаю, когда panel.xyplot находится внутри него?

sessionInfo:

 R version 4.0.2 (2020-06-22)
Platform: x86_64-apple-darwin17.0 (64-bit)
Running under: macOS Mojave 10.14.6

Matrix products: default
BLAS:   /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib

locale:
[1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] lattice_0.20-41 cluster_2.1.0  

loaded via a namespace (and not attached):
[1] compiler_4.0.2 tools_4.0.2    grid_4.0.2 
 

Комментарии:

1. Привет, Г. Гротендик, данные должны поставляться с cluster пакетом, не так ли?

Ответ №1:

panel.xyplot не может быть аргументом ifelse . Вычислите pch так же, как код вычислял col:

 library(cluster)
library(lattice)
xyplot(V8 ~ V7,
       data = flower,
       V8_var = flower$V8,
       panel = function(x, y, ..., V8_var, subscripts) {
         
         col <- ifelse(V8_var[subscripts] < 50, 'blue', 'orange')
         pch <- ifelse(V8_var[subscripts] < 50, 2, 6)
         panel.xyplot(x,y,type='p',
                        col = col,
                        pch = pch)
         
       })
 

хотя в этом случае вам даже не нужна функция panel:

 xyplot(V8 ~ V7,
       data = flower,
       col = ifelse(flower$V8 < 50, "blue", "orange"),
       pch = ifelse(flower$V8 < 50, 2, 6))
 

Комментарии:

1. Спасибо. Есть ли особая причина, по которой panel.xyplot не может быть аргументом ifelse?

2. Это должен быть вектор той же длины, что и вектор условий else длиной 1, и, кроме того, он будет вычислен, даже если он находится в ветви, которая не выбрана.