2016-11-01 2 views
1

У меня есть матрица и хотелось бы ее подмножество с помощью сопоставления и функции.подмножество матрицы с использованием сопоставления роунов и определяемой пользователем функции

Пример: случайно заполненная матрица с использованием runif и set.seed для воспроизводимости.

set.seed(1) 
exp.mat <- matrix(runif(9*6, 5.0, 10), nrow = 9, ncol = 6) 
rownames(exp.mat) <- c('a','b1','b2','b3','c','d1','d2','e1','e2') 
colnames(exp.mat) <- c('s1','s2','s3','s4','s5','s6') 

exp.mat 
     s1  s2  s3  s4  s5  s6 
a 5.353395 6.661973 6.733417 8.562573 6.198147 8.024666 
b1 5.497331 8.254352 6.668875 6.999972 5.294672 8.273620 
b2 6.581359 6.290084 7.381756 6.626761 8.211441 6.765986 
b3 7.593171 7.392726 9.460992 8.785436 9.381346 6.351301 
c 8.310025 8.831553 9.321697 6.013461 8.894573 9.963420 
d1 7.034151 5.421235 6.949948 8.555606 8.986544 8.167466 
d2 9.564380 9.376607 8.886603 5.608460 7.276372 6.066041 
e1 6.468017 6.695365 9.803090 6.227443 7.050420 5.646862 
e2 7.295329 9.197202 7.173297 5.716522 9.054351 7.390590 

Отображение с колонкой, содержащей rownrownames из исходной матрицы, столбец map, содержащих соответствующее отображение.

maps <- data.frame(rown=c('a','b1','b2','b3','c','d1','d2','e1','e1','e1'), 
        map =c('a','b','b','b','c','d','d','e','f','g')) 
maps 

    rown map 
1 a a 
2 b1 b 
3 b2 b 
4 b3 b 
5 c c 
6 d1 d 
7 d2 d 
8 e1 e 
9 e1 f 
10 e1 g 

Функция, mean рассматривается здесь для выбора строк, когда есть несколько сопоставлений (случай 2).

apply(exp.mat, 1, mean) 
     a  b1  b2  b3  c  d1  d2  e1  e2 
6.922362 6.831470 6.976231 8.160829 8.555789 7.519158 7.796410 6.981866 7.637882 

На основе отображений,

  1. если имеется только одно значение в rown отображения, чтобы map, то он должен непосредственно скопировать всю строку. например: a, c имеют только одно отображение.
  2. Если в rown имеется более одного значения, сопоставление с map, то он должен скопировать всю строку, которая имеет наибольшее значение из результирующей функции выше. например: b1, b2, b3 maps to b; b3 имеет максимально высокий mean. Таким образом, он должен выбрать b3, а также d2.
  3. если есть значение в rown, отображающее более чем одно значение в map, тогда оно должно отбросить эти строки. например: e1 имеет более одного значения отображения e, f.
  4. если нет сопоставления, то отбросьте строку. например: e2 не имеет соответствующего отображения.

Ожидаемый результат: subsetted матрица

> exp.mat.trans 
     s1  s2  s3  s4  s5  s6 
a 5.353395 6.661973 6.733417 8.562573 6.198147 8.024666 
b 7.593171 7.392726 9.460992 8.785436 9.381346 6.351301 
c 8.310025 8.831553 9.321697 6.013461 8.894573 9.963420 
d 9.564380 9.376607 8.886603 5.608460 7.276372 6.066041 

Пожалуйста, посоветуйте, как добиться этого в эффективной манере?

Я достиг этого Eyeballing и код ниже

exp.mat.trans <- exp.mat[c(1,4,5,7),] 
rownames(exp.mat.trans) <- c('a','b','c','d') 

Это может быть полезно определить только показатели, поскольку нет никакого преобразования значений?

# Index Subsetting 
ind <- c(1,4,5,7) 
exp.mat.trans2 <- exp.mat[ind,] 
rownames(exp.mat.trans2) <- maps[ind, 'map'] 

exp.mat.trans и exp.mat.trans2 такие же!

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

map и exp.mat не может быть таким же всегда!

ответ

2

Если вы хотите иметь эффективное решение, я думаю, что было бы лучше использовать data.tables для сопоставления. Ваша матрица ввода - это что-то другое, если я запустил ее.Я нашел следующее решение проблемы:

set.seed(1) 
exp.mat <- matrix(runif(9*6, 5.0, 10), nrow = 9, ncol = 6) 
rownames(exp.mat) <- c('a','b1','b2','b3','c','d1','d2','e1','e2') 
colnames(exp.mat) <- c('s1','s2','s3','s4','s5','s6') 
> exp.mat 
     s1  s2  s3  s4  s5  s6 
a 6.327543 5.308931 6.900176 6.911940 8.971199 8.946781 
b1 6.860619 6.029873 8.887226 9.348454 5.539718 5.116656 
b2 7.864267 5.882784 9.673526 6.701745 8.618555 7.386150 
b3 9.541039 8.435114 6.060713 7.410401 7.056372 8.661569 
c 6.008410 6.920519 8.258369 7.997829 9.104731 8.463658 
d1 9.491948 8.849207 5.627775 7.467707 8.235301 7.388098 
d2 9.723376 7.488496 6.336103 5.931088 8.914664 9.306047 
e1 8.303989 8.588093 6.930570 9.136867 7.765182 7.190486 
e2 8.145570 9.959530 5.066952 8.342334 7.648598 6.223986 
maps <- data.table(rown=c('a','b1','b2','b3','c','d1','d2','e1','e1'), 
        map =c('a','b','b','b','c','d','d','e','f')) 
#RULE 2 calculate mean of each row 
maps[, value := rowMeans(exp.mat)[rown]] 
# aggregate such that we know which mapping should be made (RULE 2) 
maps <- maps[, rown[which.max(value)], by = map] 
# Delete if more mappings are made first find the number of mappings (RULE 3) 
number_map <- maps[,.N, by = V1] 
setkey(maps, "V1") 
# Delete if more than one time a mapping is found 
maps <- maps[number_map[N < 2, V1]] 
# Now subset the matrix 
exp.mat.sub <- exp.mat[maps$V1[maps$V1 %in% rownames(exp.mat)],] 
rownames(exp.mat.sub) <- maps[match(maps$V1, rownames(exp.mat.sub))]$map 
exp.mat.sub 
     s1  s2  s3  s4  s5  s6 
a 6.327543 5.308931 6.900176 6.911940 8.971199 8.946781 
b 9.541039 8.435114 6.060713 7.410401 7.056372 8.661569 
c 6.008410 6.920519 8.258369 7.997829 9.104731 8.463658 
d 9.723376 7.488496 6.336103 5.931088 8.914664 9.306047 
+0

'7.564495' был присвоен до последней строки, когда' карты [, значение: = rowMeans (exp.mat)] 'была выполнена. Но значение должно было быть для 'e2'. Однако это не имеет значения, так как значение «e2» отсутствует. Кроме того, этот подход не работает, если объект 'mapping' не имеет одинаковых строк как« исходная матрица » – Prradep

+0

. Вы правы, я пытаюсь исправить эту проблему, отсортировав значение строки на основе столбца. Это работает для вас? –

+0

@ tobias-bekker: Он работает с этим примером, и я не предвижу никаких проблем. Я буду реализовывать то же самое с моей оригинальной проблемой и дам вам знать в случае возникновения проблем. Благодаря ! – Prradep

Смежные вопросы