R: Подсчитать количество валют в одном фрейме данных на основе другого и вычислить среднее между диапазоном - PullRequest
0 голосов
/ 30 октября 2019

Этот пост похож на этот , но с другим подходом. У меня есть два фрейма данных, X и Y, которые я показываю вам здесь:

X <- data.frame(V1 = c("chr1", "chr1", "chr1", "chr2", "chr2", "chr2"),
                Start = c(0, 540, 920, 0, 582, 715 ),
                Stop = c(230, 720, 1270, 350, 635, 950))

Y <- data.frame(V1 = c("chr1", "chr1", "chr1", "chr2", "chr2", "chr2"),
                Start = c(3, 16, 180,
                          15, 585, 800 ),
                Stop = c(15, 24, 201,
                         102, 612, 850),
                Dif = c(12, 8, 21,
                        87, 27, 50))

Я хочу получить Z, который:

Z <- data.frame(V1 = c("chr1", "chr1", "chr1", "chr2", "chr2", "chr2"),
                Start = c(0, 540, 920, 0, 582, 715 ),
                Stop = c(230, 720, 1270, 350, 635, 950),
                Count = c(3, 0, 0, 1, 1, 1)
                Mean = c(13.66, 0, 0, 87, 27, 50))

Что такое:

V1 = X$V1
Start = X$Start
Stop = X$Stop

Count = Количество строк Y внутри диапазона координат Start / Stop of X, которое я получаю с помощью:

    library(tidyverse)
    X %>%
    mutate(Count = pmap_int(list(V1, Start, Stop), ~filter(Y, V1 == ..1,  Start >= ..2, Stop <=..3) %>% nrow))

Mean = среднее значение разности между Y $ Start иY $ Стоп в вышеуказанном диапазоне (в первом случае это 12 + 8 + 21/3 = 13,66, потому что эти три - три валюты в Y между первым диапазоном X.

Я не знаюкак получить этот столбец Mean, потому что, когда я пытаюсь использовать аналогичный подход, который я использовал со столбцом Count, я не знаю, как использовать mean () без получения ошибки.

Ответы [ 2 ]

1 голос
/ 30 октября 2019

Рассмотрим базовые R merge:

# MERGE X AND Y AND CALCULATE Count AND Dif SUBSET
mdf <- within(merge(X, Y, by="V1", suffixes=c("", "_"), sort=FALSE), {    
         Count <- as.integer(Start <= Start_ & Stop_ <= Stop) 
         Dif_sub <- ifelse(Start <= Start_ & Stop_ <= Stop, Dif, NA)
    })

# MERGE (LEFT JOIN) AGGREGATIONS OF Count AND Mean
aggdf <-  merge(aggregate(Count ~ V1 + Start + Stop, mdf, sum),
                aggregate(cbind(Mean=Dif_sub) ~ V1 + Start + Stop, mdf, mean),
                by=c("V1", "Start", "Stop"), all.x=TRUE)
aggdf
#     V1 Start Stop Count     Mean
# 1 chr1     0  230     3 13.66667
# 2 chr1   540  720     0       NA
# 3 chr1   920 1270     0       NA
# 4 chr2     0  350     1 87.00000
# 5 chr2   582  635     1 27.00000
# 6 chr2   715  950     1 50.00000

Онлайн-демонстрация

1 голос
/ 30 октября 2019

Вот мое решение.

require("sqldf")

X <- data.frame(V1 = c("chr1", "chr1", "chr1", "chr2", "chr2", "chr2"),
                Start = c(0, 540, 920, 0, 582, 715 ),
                Stop = c(230, 720, 1270, 350, 635, 950))

Y <- data.frame(V1 = c("chr1", "chr1", "chr1", "chr2", "chr2", "chr2"),
                Start = c(3, 16, 180,
                          15, 585, 800 ),
                Stop = c(15, 24, 201,
                         102, 612, 850),
                Dif = c(12, 8, 21,
                        87, 27, 50))


Z <- sqldf("select a.*
                  -- ,b.Start as Y_Start
                  -- ,b.Stop as Y_Stop
                  -- ,b.Dif
                  ,sum(case when b.Start is not null then 1 else 0 end) as Count
                  ,avg(coalesce(b.Dif,0)) as Mean
           from X as a
           left join Y as b
           on a.V1 = b.V1
           and a.Start < b.Start
           and a.Stop > b.Stop
           group by a.V1, a.Start, a.Stop
           ")

и вот вывод:

> Z
    V1 Start Stop Count     Mean
1 chr1     0  230     3 13.66667
2 chr1   540  720     0  0.00000
3 chr1   920 1270     0  0.00000
4 chr2     0  350     1 87.00000
5 chr2   582  635     1 27.00000
6 chr2   715  950     1 50.00000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...