группирование строк данных по факторам и по функциям - вывод полной исходной строки данных - PullRequest
1 голос
/ 10 октября 2011

Мой первый пост, и я очень плохо знаком с R, так что это может быть работа. Я все время ищу решение, так что, наконец, я пишу о помощи. Дайте мне знать, если мне нужно уточнить или предоставить дополнительную информацию.

У меня большой массив данных, который выглядит следующим образом:

numReads length    name2
0        7384      Ssxb2
7904     93237     St5
3438     12969     Taf9b
0        996       Tas2r138
0        882       Tas2r143
0        960       Tas2r144
0        6761      Tbx10
8125     43804     Tdrd1
8124     43738     Tdrd1
8102     39301     Tdrd1
1227     9286      Thnsl1

Как сгруппировать данные по третьему столбцу (name2), найти значение max() для numReads и сохранить соответствующее значение длины?

Моим идеальным выводом были бы вышеуказанные данные с двумя строками, связанными с «Tdrd1», которые НЕ содержат максимальное значение для этого факторного уровня (строки со значениями 8124 и 8102).

Я пробовал tapply(), by() и aggregate(). Никто из них не может дать мне правильные результаты.

Заранее спасибо.

Редактировать после комментариев, которые пришли гораздо быстрее, чем ожидалось. Спасибо!

Идеальный пример результатов будет выглядеть следующим образом

numReads  length  name2
0        7384      Ssxb2
7904     93237     St5
3438     12969     Taf9b
0        996       Tas2r138
0        882       Tas2r143
0        960       Tas2r144
0        6761      Tbx10
8125     43804     Tdrd1
1227     9286      Thnsl1

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

Мне нравится идея агрегата () с последующим слиянием (). Но как функция merge () узнает, из какой строки исходных строк нужно извлечь значение длины, основываясь на общем уровне факторов?

Данные представляют собой снимок данных по экспрессии генов, основанных на аннотациях стенограммы. Я пытаюсь выбрать транскрипт с наибольшим выражением (с точки зрения numReads) для связанного имени2. Мне нужны данные длины для нормализации в нисходящем направлении.

РЕДАКТИРОВАТЬ после попытки использовать очень полезное предложение от ROLO. Еще раз спасибо!

также спасибо Чейзу и Дарокзигу за помощь, а также

Поэтому я пытаюсь использовать подход ddply (), чтобы разделить мой фрейм данных по 'name2', отсортировать по количеству операций чтения в порядке убывания и выбрать верхнюю строку. Это эффективно дает мне максимальное значение name2 для каждой группы и сохраняет всю мою исходную информацию, особенно длину.

К сожалению, я пытаюсь сделать это на фрейме данных с> 34 000 строк. Он отлично работает для ~ 1000 строк и даже для ~ 5000 строк, но вылетает, когда я передаю ему весь набор данных.

Я пытаюсь использовать опцию .parallel, но она заканчивается с ошибкой:

Loading required package: foreach
Error: foreach package required for parallel plyr operation

Я также пытался контролировать работу с опцией .progressbar. индикатор выполнения достигает 100%, но операция никогда не заканчивается.

Есть идеи, как применить эту операцию к моему полному набору данных?

Ответы [ 3 ]

4 голосов
/ 11 октября 2011

Используйте plyr для разделения на name2, затем выполните обратную сортировку numReads и выберите первую строку:

require(plyr)
ddply(df, "name2", function(dat) {
    dat[order(dat$numReads, decreasing=TRUE), ][1,]
})

  numReads length    name2
1        0   7384    Ssxb2
2     7904  93237      St5
3     3438  12969    Taf9b
4        0    996 Tas2r138
5        0    882 Tas2r143
6        0    960 Tas2r144
7        0   6761    Tbx10
8     8125  43804    Tdrd1
9     1227   9286   Thnsl1
0 голосов
/ 10 октября 2011

Здесь, похоже, есть два разных вопроса.Первый можно решить с помощью пакета plyr:

library(plyr)
txt <- "numReads length    name2

0   7384    Ssxb2
7904  93237      St5
3438  12969    Taf9b
0    996 Tas2r138
0    882 Tas2r143
0    960 Tas2r144
0   6761    Tbx10
8125  43804    Tdrd1
8124  43738    Tdrd1
8102  39301    Tdrd1
1227   9286   Thnsl1
"

dat <- read.table(textConnection(txt), header = TRUE)

ddply(dat, "name2", summarize, max = max(numReads))

Дает вам:

     name2  max
1    Ssxb2    0
2      St5 7904
3    Taf9b 3438
4 Tas2r138    0
5 Tas2r143    0
6 Tas2r144    0
7    Tbx10    0
8    Tdrd1 8125
9   Thnsl1 1227

На второй вопрос, по-видимому, можно ответить:

dat[dat$name2 == "Tdrd1" & dat$numReads != max(dat$numReads[dat$name2 == "Tdrd1"]),]

   numReads length name2
9      8124  43738 Tdrd1
10     8102  39301 Tdrd1

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

0 голосов
/ 10 октября 2011

Я не могу точно получить то, что вы ищете, но я думаю вы хотите получить строки из базы данных, которые имеют самое высокое значение в numReads для уровня name2.Это может быть сделано легко, например.с aggregate и более поздними merge.

Ваш демонстрационный набор данных:

df  <- structure(list(numReads = c(0L, 7904L, 3438L, 0L, 0L, 0L, 0L, 
8125L, 8124L, 8102L, 1227L), length = c(7384L, 93237L, 12969L, 
996L, 882L, 960L, 6761L, 43804L, 43738L, 39301L, 9286L), name2 = structure(c(1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 8L, 8L, 9L), .Label = c("Ssxb2", 
"St5", "Taf9b", "Tas2r138", "Tas2r143", "Tas2r144", "Tbx10", 
"Tdrd1", "Thnsl1"), class = "factor")), .Names = c("numReads", 
"length", "name2"), class = "data.frame", row.names = c(NA, -11L
))

Давайте сгруппируем фрейм данных по name2 с функцией max:

> df.a <- aggregate(numReads ~ name2, df, max)
> df.a
     name2 numReads
1    Ssxb2        0
2      St5     7904
3    Taf9b     3438
4 Tas2r138        0
5 Tas2r143        0
6 Tas2r144        0
7    Tbx10        0
8    Tdrd1     8125
9   Thnsl1     1227

И объединить исходные значения length с фреймом данных (df.a):

> merge(df.a, df)
     name2 numReads length
1    Ssxb2        0   7384
2      St5     7904  93237
3    Taf9b     3438  12969
4 Tas2r138        0    996
5 Tas2r143        0    882
6 Tas2r144        0    960
7    Tbx10        0   6761
8    Tdrd1     8125  43804
9   Thnsl1     1227   9286

Надеюсь, я не понял ваш вопрос!

...