代码之家  ›  专栏  ›  技术社区  ›  user1420372

将ggplot2中的密度图缩放为具有相同的X轴范围

  •  1
  • user1420372  · 技术社区  · 8 年前

    我想覆盖两个密度图;一个是转换前的数据,另一个是转换后的数据。我不关心x和y值,只关心曲线的形状。

    我想将给定预测器的两个图表叠加在一起,即使X轴是不同的。我发现很难从两个方面看问题。在现实中,也会有更多的情节,因此将未转换和转换的数据结合到一个是最好的解决方案。

    library(tidyverse)
    require(caret)
    data(BloodBrain)
    bbbTrans <- preProcess(select(bbbDescr, adistd, adistm, dpsa3, inthb), method = "YeoJohnson")
    bbbTransData <- predict(bbbTrans, select(bbbDescr, adistd, adistm, dpsa3, inthb)) 
    dat <- bbbTransData %>%
      gather(Predictor, Value) %>%
      mutate(Transformation = "Yeo-Johnson") %>%
      bind_rows(data.frame(gather(select(bbbDescr, adistd, adistm, dpsa3, inthb), Predictor, Value), Transformation = "NA", stringsAsFactors = FALSE))  
    
    
    
    # For the predictor adistd, I would like the x-axis range to be 0:12.5 for the
    # "Yeo-Johnson" transformation and 0:250 for no transformation.  In this plot, it
    # is hard to see the shape of the transformed variables due to the different x-value range.
    dat %>% ggplot(aes(x = Value, color = Transformation)) +  
      geom_density(aes(y = ..scaled..), position = "dodge") + 
      facet_wrap(~Predictor, scales = "free")
    
    
    # i.e., I want to superimpose the 2 charts for a given Predictor on top of each other, even though the x-axis is different
    # I find it hard to look across the two facets.  In reality, as well, there will be a lot more plots, so combining the non-transformed and transformed data into the one plot using colour would be the best solution.
      filter(dat, Transformation != 'NA') %>% ggplot(aes(x = Value, y = ..scaled..)) +  
      geom_density() + 
      facet_wrap(~Predictor, scales = "free")
    
      filter(dat, Transformation == 'NA') %>% ggplot(aes(x = Value, y = ..scaled..)) +  
      geom_density() + 
      facet_wrap(~Predictor, scales = "free")
    

    编辑:我认为我需要的算法是(并且更喜欢使用tidyverse):

    1. 按预测/转换分组
    2. 获取每个的密度
    3. 将密度x转换为(x-xmin)/(xmax-xmin),以便在0到1之间
    4. 绘图转换密度$X,密度$Y
    1 回复  |  直到 8 年前
        1
  •  1
  •   pogibas    8 年前

    可扩展的解决方案( base::scale )计算密度( stats::density )。 density 函数输出相同数量的等距点,以便我们可以从 0 1 (按运营商要求)。

    # How many points we want 
    nPoints <- 1e3
    
    # Final result
    res <- list()
    
    # Using simple loop to scale and calculate density
    combinations <- expand.grid(unique(dat$Predictor), unique(dat$Transformation))
    for(i in 1:nrow(combinations)) {
        # Subset data
        foo <- subset(dat, Predictor == combinations$Var1[i] & Transformation == combinations$Var2[i])
        # Perform density on scaled signal
        densRes <- density(x = scale(foo$Value), n = nPoints)
        # Position signal from 1 to wanted number of points
        res[[i]] <- data.frame(x = 1:nPoints, y = densRes$y, 
                               pred = combinations$Var1[i], trans = combinations$Var2[i])
    }
    res <- do.call(rbind, res)
    ggplot(res, aes(x / nPoints, y, color = trans, linetype = trans)) +
        geom_line(alpha = 0.5, size = 1) +
        facet_wrap(~ pred, scales = "free")
    

    enter image description here

    推荐文章