R рассчитать итоговый фрейм данных из фрейма данных с несколькими столбцами информации

У меня есть кадр данных с несколькими столбцами информации, например:

df <- data.frame(chr=c("chr1", "chr1", "chr1", "chr1", "chr1", "chr1", "chr1", "chr1", "chr2", "chr2"), Gene=c("Happy", "Happy", "Happy", "Happy", "Happy", "Happy", "Happy", "Happy", "Sad", "Sad"), site = c(100, 120, 130, 300, 2000, 2300, 2342, 2451, 120, 123), value=c(20, 25, 21, 30, -80, 31, -79, -90, 10, 13))

> df
    chr  Gene site value
1  chr1 Happy  100    20
2  chr1 Happy  120    25
3  chr1 Happy  130    21
4  chr1 Happy  300    30
5  chr1 Happy 2000   -80
6  chr1 Happy 2300    31
7  chr1 Happy 2342   -79
8  chr1 Happy 2451   -90
9  chr2   Sad  120    10
10 chr2   Sad  123    13

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

df$Distance <- c(1001, diff(df$site, lag=1, differences=1))

> df
    chr  Gene site value Distance
1  chr1 Happy  100    20     1001
2  chr1 Happy  120    25       20
3  chr1 Happy  130    21       10
4  chr1 Happy  300    30      170
5  chr1 Happy 2000   -80     1700
6  chr1 Happy 2300    31      300
7  chr1 Happy 2342   -79       42
8  chr1 Happy 2451   -90      109
9  chr2   Sad  120    10    -2331
10 chr2   Sad  123    13        3

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

   Gene PositiveClusters NegativeClusters
1 Happy                1                1
2   Sad                1                0

person user2165857    schedule 20.11.2014    source источник
comment
@beginneR Я считаю кластером группу сайтов, где расстояние между двумя сайтами не превышает 1000. Вот почему я рассчитал расстояние между двумя сайтами так, чтобы, если расстояние больше 1000, этот сайт был началом нового кластера.   -  person user2165857    schedule 20.11.2014


Ответы (1)


Вот решение data.table, но у меня есть ощущение, что есть более эффективный способ...

library(data.table)
setDT(df)[,cluster:=c(0,cumsum(diff(site)>1000)),by=Gene]
df[,mean:=mean(value),by=list(Gene,cluster)]
df[,list(pos=length(unique(cluster[mean>=0])),
         neg=length(unique(cluster[mean<0]))),by=Gene]
#     Gene pos neg
# 1: Happy   1   1
# 2:   Sad   1   0

Итак, это преобразует df в data.table и добавляет столбец cluster на основе cumsum(diff(site)>1000), сгруппированного по Gene. Это очень типичный шаблон для создания группирующих переменных.

Затем мы добавляем столбец mean, который mean(value) сгруппирован по Gene и cluster.

Затем мы создаем новую таблицу data.table, в которой есть счетчики каждого типа кластера для среднего положительного (>= 0) или отрицательного (‹ 0), сгруппированные по Gene.

person jlhoward    schedule 20.11.2014