Соотнесите индексы, где два кадра данных равны элементам в другом массиве - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть массив cluster_true и фрейм данных data, содержащий в каждой строке 2D-координату.Я хочу сохранить в другом фрейме данных информацию о том, сколько раз для заданной 2D-координаты появлялся каждый элемент в cluster_true.Так, например, для координаты (1,1) я хочу проверить все строки в data, первые два столбца которых имеют значение 1, а затем проверить значения cluster_true для этих индексов.Вот пример, чтобы прояснить его (он дает желаемый результат):

# Example variables
cluster_true = c(1,2,1,1,2,2,1,2,2,2,2,1,1)
x = 3
y = 3
data = data.frame(X = c(1,1,0,0,2,1,1,0,0,0,1,1,1),
                  Y = c(1,1,2,1,2,2,1,0,0,0,0,2,0))

# Names of the columns
plot_colnames = c('X', 'Y', paste('cluster',unique(cluster_true),sep='_'))
# Empty dataframe with the right column names
plot_df = data.frame(matrix(vector(), x*y, length(plot_colnames),
                            dimnames=list(c(), plot_colnames)),
                     stringsAsFactors=F)
# Each row belongs to a certain 2D coordinate
plot_df$X = rep(1:x, y)-1
plot_df$Y = rep(1:x, each = y)-1
# This is what I don't know how to improve
for(i in 1:nrow(plot_df)){
  idx = which(apply(data[,1:2], 1, function(x) all(x == plot_df[i,1:2])))
  plot_df[i,3] = sum(cluster_true[idx] == 1)
  plot_df[i,4] = sum(cluster_true[idx] == 2)
}
print(plot_df)

Вещи, которые мне нужно изменить, и я не знаю, как:

  • Я думаюпетли можно было бы избежать, чтобы получить более элегантное решение, но я не знаю как.Фрейм данных data может иметь очень большое количество строк, поэтому эффективный код будет потрясающим.
  • Внутри цикла я жестко закодировал кластеры для проверки (последние две строки внутри цикла предполагают, что язнать, какие числа присутствуют в cluster_true и какому столбцу plot_df они соответствуют).Фактически, элементы в cluster_true могут быть чем угодно, даже непоследовательными числами (т. Е. cluster_true = c(1,5,5,5,56,10,19,10)).

Итак, я хочу знать, можно ли это сделать без цикла икак можно более универсальным.

1 Ответ

0 голосов
/ 16 сентября 2018

Если я правильно понимаю, ОП хочет

  • найти индексы строк для всех уникальных комбинаций X, Y координат в data,
  • , найти значение всоответствующие строки cluster_true,
  • подсчитывают количество вхождений каждого значения для данной комбинации X, Y, а
  • выводят результаты в широкоформатном формате.

Эту проблему можно решить путем объединения и изменения формы:

library(data.table) # version 1.11.4 used
library(magrittr)   # use piping to improve readability
# unique coordinate pairs
uni_coords <- unique(setDT(data)[, .(X, Y)])[order(X, Y)]
# join and lookup values in cluster_true
data[uni_coords, on = .(X, Y), cluster_true[.I], by = .EACHI] %>% 
  # reshape from long to wide format, thereby counting occurrences
  dcast(X + Y ~ sprintf("cluster_%02i", V1), length)
   X Y cluster_01 cluster_02
1: 1 1          2          1
2: 1 2          1          1
3: 1 3          1          1
4: 2 2          0          1
5: 3 1          1          0
6: 3 2          1          0
7: 3 3          0          3

Это совпадает с ожидаемым результатом OP, за исключением комбинаций координат, которые не отображаются в data.

setDT(plot_df)[order(X, Y)]
   X Y cluster_1 cluster_2
1: 1 1         2         1
2: 1 2         1         1
3: 1 3         1         1
4: 2 1         0         0
5: 2 2         0         1
6: 2 3         0         0
7: 3 1         1         0
8: 3 2         1         0
9: 3 3         0         3

Преобразование имеет то преимущество, что оно может обрабатывать произвольные значения в cluster_true в соответствии с запросом OP.

Редактировать

ОП запросил , чтобы все возможные комбинации X, Y координат были включены в окончательный результат.Это может быть достигнуто с помощью перекрестного соединения CJ() для вычисления uni_coords:

# all possible  coordinate pairs
uni_coords <- setDT(data)[, CJ(X = X, Y = Y, unique = TRUE)]
# join and lookup values in cluster_true
data[uni_coords, on = .(X, Y), cluster_true[.I], by = .EACHI][
  uni_coords, on = .(X, Y)] %>% 
  # reshape from long to wide format, thereby counting occurrences
  dcast(X + Y ~ sprintf("cluster_%02i", V1), length) %>% 
  # remove NA column from reshaped result
  .[, cluster_NA := NULL] %>% 
  print() 
   X Y cluster_01 cluster_02
1: 1 1          2          1
2: 1 2          1          1
3: 1 3          1          1
4: 2 1          0          0
5: 2 2          0          1
6: 2 3          0          0
7: 3 1          1          0
8: 3 2          1          0
9: 3 3          0          3
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...