Векторизация вложенная для циклов r - PullRequest
0 голосов
/ 28 февраля 2019

У меня возникла небольшая проблема при попытке векторизовать вложенный цикл for в R.
По сути, программа ищет определенное кодированное значение во фрейме данных, находит этот код в именованном списке и сохраняетчто значение кодирует в векторе.В конце я связываю все эти векторы вместе, чтобы создать матрицу некодированных значений.Хотя я довольно новичок в функциональном программировании и хотел бы как-то оптимизировать этот процесс, но я не могу понять, как заставить это работать без циклов for!

rawdata это закодированные значения.Каждый столбец в rawdata - это вопрос, который задают опрашивающим.Выглядит это так:

q1 q2 q3
a1 b1 c1
a2 b2 c2
a3 '' ''

коды данных - это фрейм данных списков каждого вопроса и их возможных кодов.

Обратите внимание, что a3 отсутствует в списке дляq1.Бывает, что иногда ответа нет в кодексе, поэтому я хочу сохранить функциональность, при которой, если происходит такой случай, вводится код, а не NA. l - список, в котором каждый вопрос является именованным списком кодов и ответов.Это похоже на коды данных , но это список именованных списков, поэтому он выглядит так:

l = list(q1=list(a1=alpha,a2=beta), q2=list(b1=gamma,b2=delta)...) 

и так далее.Вот код:

#Checks each "cell" to see if the code is within the codex pertaining
# to the question asked, if it is, then the decoded value is stored
#if not, then the coded value is stored in the vector

for (column in 1:length(rawdata)){
  for (row in 1:length(rawdata$column1)){
    codex<-l[[colnames(rawdata)[i]]]
    code<-rawdata[[colnames(rawdata)[i]]][row]
    keys<-datacodes$data[[i]]$key
    if(code %in% keys){
      p[row]<-codex[[as.character(code)]]
    }
    else{
      p[row]<-code
      }
    }
  }
#tacks on each finished vector to form a matrix
decode<-cbind(decode,p)
}

На выходе должно быть что-то вроде:

q1    q2    q3
alpha gamma epsilon
beta  delta zeta
a3    ''    ''

1 Ответ

0 голосов
/ 28 февраля 2019

Вот возможное решение путем удаления интер-цикла и использования функции match.Это создает копию исходных данных и затем подставляет в соответствие значения из определенного списка «l».Поскольку это именованный список, легко получить требуемый список значений для подстановки.

rawdata<-read.table(header = TRUE, text="q1 q2 q3
a1 b2 c1
a2 b1 c2
a3 b1 ''")

l = list(q1=list(a1="alpha",a2="beta"), q2=list(b1="gamma",b2="delta"), q3=list(c1="epsilon",c2="zeta")) 

#make copy of data to update
answer<-rawdata

#loop through the question columns in rawdata
for (n in names(rawdata)) {
   #match the answer to the provide list
   mat<-match(rawdata[[n]], names(l[[n]]))

   #convert from factors to character type
   answer[[n]]<-as.character(answer[[n]])

   #Remove any NA answers and 
   #update the rows and column in the copy of the original data
   answer[[n]][which(!is.na(mat))]<- unlist(l[[n]][mat[!is.na(mat)]])
}
answer

     q1    q2      q3
1 alpha delta epsilon
2  beta gamma    zeta
3    a3 gamma        

Если в зависимости от количества ответов по сравнению с количеством вопросов определить степень улучшения производительности.

Примечание. Я обновил данные вашего примера, чтобы улучшить тестирование.

...