Р;Заполнение матрицы циклом for, повторяющимся над вектором - PullRequest
0 голосов
/ 31 декабря 2018

Я не очень разбираюсь в R и несколько дней пытался повторить строку кода, чтобы заполнить матрицу данных.Мой инстинкт - создать цикл for.

Я студент-биолог, работающий над различиями цветов между наборами изображений и использующий цветопередачу пакета R.Соответствующие данные были загружены в R в виде списка матриц 8x4 (каждая матрица описывает цвета в одном изображении).Пять изображений составляют один набор, и всего их 100.Каждый набор идентифицируется номером (не 1-100, это прерванная последовательность, но я сохранил последовательность чисел в векторе, называемом «нумератором»).Я написал код для извлечения нужных данных в правильном формате для первого набора, и он выглядит следующим образом:

## extract the list of matrices belonging to the first set (A3) from the the full list
A3<-histlist[grep('^3',names(histlist))] 
## create a colour distance matrix (cdm), ie a pairwise comparison of "similarity" between the five matrices stored in A3
cdm3<-colordistance::getColorDistanceMatrix(A3, method="emd", plotting=FALSE)
## convert to data frame to fix row names
cdm3df<-as.data.frame(cdm3) 
## remove column names
names(cdm3df)<-NULL 
## return elements in the first row and column 2-5 only (retains row names).
cdm3filtered<-cdm3df[1,2:5]

Теперь я хочу заменить «3» в приведенном выше коде на каждое число в'listlist' (не уверен, должны ли они быть как .factor или как .numeric).У меня было много попыток, начиная с for (i in numberlist) {...}, но без успешного вывода.Для меня имеет смысл хранить выходные данные цикла в матрице хранения;matrix(nrow=100,ncol=4) но я очень застрял и не могу заполнить свою матрицу хранения построчно, повторяя код выше ...

Любая помощь будет принята с благодарностью!

Обновления

Как я хочу, чтобы выходы цикла выглядели так (+ добавлено в матрицу хранения);

> cdm17filtered                                
17clr 0.09246918 0.1176651 0.1220622 0.1323586

Это моя попытка:

for (i in numberlist$X) {
  A[i] <- histlist[grep(paste0('^',i),names(histlist))]
  cdm[i] <- colordistance::getColorDistanceMatrix(A[i], method="emd", plotting=FALSE)
  cdm[i]df <- as.data.frame(cdm[i])
  cdm[i]filtered <- cdm[i]df[1,2:5]
  print(A[i]) # *insert in n'th column of storage matrix
}

Вышене работает, и мне не хватает последнего бита, необходимого для сохранения выходных данных цикла в матрице хранения.(Мне посоветовали не использовать rbind для заполнения матрицы хранения, потому что она медленная ..)

1 Ответ

0 голосов
/ 01 января 2019

В вашей попытке вы используете недопустимые имена R с не-буквенно-цифровыми символами, не экранированными, cdm[i]df и cdm[i]filtered.Кажется, вы намереваетесь индексировать из более крупного контейнера, например, списка объектов.

Чтобы правильно обобщить процесс для всех элементов в numberlist , настройте настройку ^3.В частности, создавать пустые списки и в цикле итеративно назначать их по индексу [i]:

# INITIALIZE LISTS (SAME LENGTH AS numberlist)
A <- vector(mode="list", length = length(numberlist))
cdm_matrices <- vector(mode="list", length = length(numberlist))
cdm_dfs <- vector(mode="list", length = length(numberlist))
cdm_filtered_dfs  <- vector(mode="list", length = length(numberlist))

# POPULATE LISTS
for (i in numberlist$X) {
  ## extract the list of matrices belonging to the first set
  A[i] <- histlist[grep(paste0('^', i), names(histlist))] 

  ## create a colour distance matrix (cdm)
  cdm_matrices[i] <- colordistance::getColorDistanceMatrix(A[i], method="emd", plotting=FALSE)

  ## convert to data frame to fix row names and remove column names
  cdm_dfs[i] <- setNames(as.data.frame(cdm_matrices[i]), NULL)

  ## return elements in the first row and column 2-5 only (retains row names).
  cdm_filtered_dfs[i] <- cdm_dfs[i][1,2:5]
}

В качестве альтернативы, если вам нужен только последний объект, cdm_filtered_df возвращается, используйте lapply там, где вы делаетене нужно использовать или индексировать списки, и все объекты являются локальными в области действия функции (т. е. никогда не сохраняются в глобальной среде):

cdm_build <- function(i) {
  A <- histlist[grep(paste0('^', i), names(histlist))]    
  cdm <- colordistance::getColorDistanceMatrix(A, method="emd", plotting=FALSE)    
  cdm_df <- setNames(as.data.frame(cdm), NULL)    
  cdm_filtered_df <- cdm_df[1,2:5]

  return(cdm_filtered_df)    # REDUNDANT AS LAST LINE IS RETURNED BY DEFAULT
}

# LIST OF FILTERED CDM DATA FRAMES
cdm_filtered_dfs <- lapply(numberlist, cdm_build)

Наконец, при любом из указанных выше решений следует создатьотдельный фрейм данных, запустите rbind в do.call():

cdm_final_df <- do.call(rbind, cdm_filtered_dfs)
...