2015-11-10 3 views
0

Я ищу способ построения распределения средних значений одной переменной через ячейки значений log2 другой переменной (который имеет положительные и отрицательные значения), используя более сложные функции в ggplot2. Я думаю, что я значительно усложняю это, и он, вероятно, жестко закодирован в ggplot2 уточненных вариантах, но я не могу понять это правильно, поэтому, прежде чем вернуться к основам, я подумал, что могу попытаться научиться применять эти функции здесь.R ggplot2 логарифмический разрез с отрицательными и положительными значениями по оси x и средним значением для бункера оси y

value <- rnorm(1000,0,20) 
dist = c(rep(0, 15), sample(1:490), sample(-1:-495)) 
data = data.frame(value=value, dist=dist) 

data$log=log2(abs(data$dist)+1) 
# re-lable the x-axis: 
data$Labels=2^(abs(data$log))-1 

data$bins=cut(data$log, breaks=10) 
# Try to recover the negative log after transformation 
data$sign=ifelse(data$dist==0, 0, ifelse(data$dist>0, "+", "-")) 

# find the average expression of value per each bin 
data=with(data, aggregate(data$value, by = list(bins, sign), FUN = function(x) c(mn =mean(x), n=length(x)))) 
data= as.data.frame(as.list(data)) 
names(data)=c("bins", "sign", "mean", "length") 

# I am doing this in a very contorted way to try to achieve what I would like which is something like this: 

bin_num = do.call("rbind", lapply(strsplit(sapply(as.character(data$bins), function(x) substr(x, 2, nchar(x)-1)), ","), as.numeric)) 
data$bin_num=bin_num[,1] 
data$bin_num=ifelse(data$sign==0, 0, ifelse(data$sign=="-", -data$bin_num, data$bin_num)) 
data = data[order(data$bin_num),] 

data <- transform(data, x2 = factor(paste(sign, bins))) 
data <- transform(data, x2 = reorder(x2, rank(bin_num))) 

# Line plot to show the distribution of the means across the bins of log2 of x: 
ggplot(data, aes(y = mean, x = bin_num, group=1)) + geom_point() + geom_line() 

# Тогда я пытаюсь повторно маркировать логарифмические преобразования здесь путем добавления метки, но, конечно, это не работает:

ggplot(data, aes(y = mean, x = bin_num, group=1)) + geom_point() + geom_line() + scale_x_discrete(labels=data$dist, breaks=data$bin_num) 

Я вижу, что ggplot2 имеет функциональные возможности непосредственно вычислить среднее поэтому мне, возможно, даже не нужны предыдущие команды. Я пробовал:

ggplot(data, aes(x = bins, y = mean)) + stat_summary(fun.y = "mean") +  geom_line() + scale_x_continuous(breaks = labels) 

Но, конечно, это не работает ... Я также видел, что ggplo2 имеет функции для автоматического помочь с логарифмической мечения вместо того, что я здесь, но я не вижу, как сделайте это, когда есть отрицательные значения для регистрации. Существует очень хорошая функция из другого вопроса here, который преобразует два значения, но я не вижу его полезным на этом этапе. Большое спасибо за любые предложения о том, как это сделать ... действительно оценили!

+0

Вы можете разделить изображение/рисунок того, что вы пытаетесь достигать. – David

+0

Привет, Дэвид, я добавил попытку, которая примерно делает то, что я пытаюсь достичь, но она очень искажена ... Я надеюсь, что есть лучший способ ... – user971102

+0

TBH, я абсолютно потерян и понятия не имею, что вы пытаются достичь ... Итак, на оси x вы хотите иметь номер ячейки, ось y отображает среднее значение этого бункера. Скажем, мы видим точку в (-10, 3), что означает, что в бункере -10 среднее значение переменной равно 3 ?! Как насчет размера бункера? А что с лог-трансформацией? – David

ответ

1

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

код воспроизводит вопрос с более коротким и более быстрый код

library(data.table) 

# function that returns the lower bound of a cut 
lower.bound <- function(x, n) { 
    c <- cut(x, n) 
    tmp <- substr(x = c, start = 2, stop = regexpr(",", c) - 1) 
    return(as.numeric(tmp)) 
} 

nbin <- 10 
set.seed(123) 
dat <- data.table(value = rnorm(1000,0, 20), 
        dist = c(rep(0, 15), sample(1:490), sample(-1:-495))) 

dat[, log := log2(abs(dist) + 1)] 
dat[, labels := 2^(abs(log))] 
dat[, sign := ifelse(dist == 0, 
        0, 
        ifelse(dist > 0, "+", "-"))] 

dat[, bin := ifelse(sign == 0, 
        0, 
        ifelse(sign == "+", 
          lower.bound(log, nbin), 
          -lower.bound(log, nbin)))] 

sumdat <- dat[, .(mvalue = mean(value), 
        nvalue = .N, 
        ylab = mean(dist)), 
       by = .(bin, sign)][order(bin)] 

ggplot(sumdat, aes(x = ylab, y = mvalue)) + geom_line() 
+0

См. Здесь для дальнейшего обсуждения: http://chat.stackoverflow.com/rooms/94732/discussion-between-david-and-user2183097 После этого я уточню окончательный ответ – David

+0

Спасибо, Дэвид ... Я искал чтобы обозначить ось х исходными не логарифмическими значениями, так что диапазон по оси х равен (dat $ dist) [1] -495 490, возможно ли это? – user971102

+0

Благодаря Давиду это прекрасно работает: sumdat <- dat [,. (Mvalue = mean (value), nvalue = .N, ylabel = mean (dist)), by =.(bin, sign)] [order (bin)] ggplot (sumdat, aes (x = ylabel, y = mvalue)) + geom_line() – user971102

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