оператор ifelse, возвращающий элемент условной матрицы в R

#r #if-statement

#r #if-оператор

Вопрос:

Я пытаюсь проверить каждую строку моего фрейма данных на наличие условия без использования forloop в r, и чтобы возвращаемый элемент был элементом отдельной матрицы, которая соответствует условиям. Вот пример:

 ax <- matrix(data=c("x","UP","DN","x"),nrow=2,dimnames=list(c("site1","site2"),c("site1","site2")))
data <- data.frame(Location1=c("site1","site1","site2","site1","site2","site2","site2","site1"),Location2=c("site1","site2","site1","site2","site2","site2","site1","site1"))
  

В результате получается матрица (ax) и фрейм данных (data):

    > ax
        site1 site2 
  site1 "x"   "DN"  
  site2 "UP"  "x"


> data
  Location1 Location2 
1    site1     site1        
2    site1     site2        
3    site2     site1       
4    site1     site2        
5    site2     site2        
6    site2     site2        
7    site2     site1       
8    site1     site1        
  

Теперь, если местоположение 1 отличается от местоположения 2, я хотел бы получить соответствующий элемент матрицы, который сообщает мне направление этого движения. Я использовал подобные инструкции ifelse раньше, но получение правильного вывода действительно ускользает от меня при попытке запросить отдельную матрицу.. Мой код является:

 data$movement <-ifelse(data$Location1!=data$Location2,ax[as.character(data$Location1),as.character(data$Location2)],"x")
  

Но это приводит к такому выводу:

 data
  Location1 Location2 movement
1    site1     site1        x
2    site1     site2        x
3    site2     site1       UP
4    site1     site2        x
5    site2     site2        x
6    site2     site2        x
7    site2     site1       UP
8    site1     site1        x
  

Кажется, что это было бы простой проблемой, но, похоже, я не могу в этом разобраться, любая помощь приветствуется

Ответ №1:

На самом деле вы можете использовать матрицу из имен строк и столбцов или индексов для подмножества матрицы.

При таком обозначении ваша проблема является однострочной:

 data$movement = ax[as.matrix(data)]

data
#   Location1 Location2 movement
# 1     site1     site1        x
# 2     site1     site2       DN
# 3     site2     site1       UP
# 4     site1     site2       DN
# 5     site2     site2        x
# 6     site2     site2        x
# 7     site2     site1       UP
# 8     site1     site1        x
  

Ваш ifelse не работает, потому что ifelse требуется, чтобы тест, результат «да» и результат «нет» были векторами одинаковой длины. Однако ваш положительный результат таков:

 ax[as.character(data$Location1),as.character(data$Location2)]
#       site1 site2 site1 site2 site2 site2 site1 site1
# site1 "x"   "DN"  "x"   "DN"  "DN"  "DN"  "x"   "x"  
# site1 "x"   "DN"  "x"   "DN"  "DN"  "DN"  "x"   "x"  
# site2 "UP"  "x"   "UP"  "x"   "x"   "x"   "UP"  "UP" 
# site1 "x"   "DN"  "x"   "DN"  "DN"  "DN"  "x"   "x"  
# site2 "UP"  "x"   "UP"  "x"   "x"   "x"   "UP"  "UP" 
# site2 "UP"  "x"   "UP"  "x"   "x"   "x"   "UP"  "UP" 
# site2 "UP"  "x"   "UP"  "x"   "x"   "x"   "UP"  "UP" 
# site1 "x"   "DN"  "x"   "DN"  "DN"  "DN"  "x"   "x"  
  

который легко преобразуется в вектор, но тогда это неправильная длина. Диагональ этой матрицы является вашим желаемым результатом, поэтому вы могли бы использовать diag(ax[as.character(data$Location1),as.character(data$Location2)]) в ifelse , или вы могли бы даже использовать

 data$movement = diag(ax[as.character(data$Location1), as.character(data$Location2)])
  

но приведенный выше способ еще лучше.