#r
#r
Вопрос:
У меня есть большой набор данных с одним столбцом названий генов и 4 столбцами методов обнаружения (в данном случае я назвал их X1, X2, X3 и X4). Я хотел бы выбрать строки, в которых гены выбраны по крайней мере 2 методом обнаружения. Примером таблицы является:
Table:
Row Gene X1 X2 X3 X4
1 A 1 0 0 0
2 A 0 0 1 0
3 A 0 1 0 0
4 B 0 0 1 0
5 B 0 0 1 0
6 C 0 0 0 1
7 D 0 0 1 0
8 D 0 1 0 0
9 D 0 1 0 0
10 E 0 0 1 0
11 E 0 0 1 0
Таким образом, я хочу выбрать строки 1,2,3 (методы X1, X2 и X3 обнаружили ген A) и строки 7,8,9, где методы X2 и X3 обнаружили ген D.
Спасибо за вашу помощь.
Комментарии:
1. Не могли бы вы поделиться некоторым кодом того, что вы уже пробовали? Как правило, вы можете просто вычислить сумму по X1: X4 для каждого гена, а затем отфильтровать строки / гены, где сумма> = 2.
2. Альтернативой было бы просто посчитать столбец «Gene», поскольку кажется, что ген появляется столько раз, сколько он был обнаружен, т. Е. Ген A обнаружен 3 раза, ген C обнаружен только один раз.
3. Обратите внимание, что в примере OP генами, которые должны давать положительное совпадение, являются A и D, все строки которых составляют 1, а не 2.
Ответ №1:
Вы можете использовать rowsum
и rowSums
для поиска тех, у кого более 1 метода, и %in%
для поиска совпадающих строк.
x <- rowSums(rowsum(zz[3:6], zz[,2]) > 0) > 1
zz$Row[zz$Gene %in% names(x[x])]
#[1] 1 2 3 7 8 9
Ответ №2:
Чтобы показать, какие гены были обнаружены двумя или более методами, это сработает.
Краткая версия:
если zz
это ваш data.frame, то:
yy <- by(zz, zz$Gene, function(dat) {sum(apply(dat[,-c(1,2)], 2, any)) >= 2} )
zz[zz$Gene %in% which(yy),]
Длинная версия
# load the data:
zz <- read.table(header = TRUE, text = "
Row Gene X1 X2 X3 X4
1 A 1 0 0 0
2 A 0 0 1 0
3 A 0 1 0 0
4 B 0 0 1 0
5 B 0 0 1 0
6 C 0 0 0 1
7 D 0 0 1 0
8 D 0 1 0 0
9 D 0 1 0 0
10 E 0 0 1 0
11 E 0 0 1 0")
# now check, gene by gene, whether at least two columns have at least one 1.
# note that the repeated any() statements can be replaced by a loop or
# apply(), but for only four columns this works, is easy enough to type,
# and much easier to understand
yy <- by(zz, zz$Gene, function(dat) {(any(dat$X1)
any(dat$X2)
any(dat$X3)
any(dat$X4) ) >= 2} )
# or, the apply way, in case there are a lot of columns.
# "-c(1,2)" as a column index means "every column except the first two",
# so if the data has 3, 4, or 30 methods, this code stays the same.
yy <- by(zz, zz$Gene, function(dat) {sum(apply(dat[,-c(1,2)], 2, any)) >= 2} )
yy
zz$Gene: A
[1] TRUE
---------------------------------------------------------------------------
zz$Gene: B
[1] FALSE
---------------------------------------------------------------------------
zz$Gene: C
[1] FALSE
---------------------------------------------------------------------------
zz$Gene: D
[1] TRUE
---------------------------------------------------------------------------
zz$Gene: E
[1] FALSE
Теперь, чтобы найти соответствующие строки для генов, которые получили TRUE
результаты.
Найдите имена zz
(A, B, C, … ), которые соответствуют yy
значениям TRUE
, и индексируйте data.frame на основе этого…
which(yy) # equivalent to which(yy == TRUE)
дает
A D
1 4
и
names(which(yy))
дает
[1] "A" "D"
итак…
zz[zz$Gene %in% names(which(yy)),]
дает
Row Gene X1 X2 X3 X4
1 1 A 1 0 0 0
2 2 A 0 0 1 0
3 3 A 0 1 0 0
7 7 D 0 0 1 0
8 8 D 0 1 0 0
9 9 D 0 1 0 0
Комментарии:
1. Спасибо, Джейсон! это работает отлично, я просто меняю == на%в%, потому что я получал это предупреждение «более длинная длина объекта не кратна более короткой длине объекта», которое%в% исправлено
2. Упс. Ошибка синхронизации копирования и вставки. Спасибо за уловку.