簡體   English   中英

R ggplot2 geom_smooth-單調平滑函數

[英]R ggplot2 geom_smooth - monotonic smoothing function

可以使geom_smooth產生單調遞減函數嗎?

第一個示例看起來單調遞減:

library(tidyverse)

df <- structure(list(x = c(-55, 11, 19, 123, 133, 123, 123, 2, 86, 
84, 179, 179, 179, 179, 25, 85, 84, 179, 179, 179, 179, 25, 86, 
84, 179, 179, 179, 179, 25, 86, 84, 179, 179, 179, 179, 25, 86, 
70, 123, 123, 123, 123, 0, -45, -45, -17, -17, -17, -17, -63, 
48, 40, 67, 67, 67, 67, -25, 11, 10, 67, 67, 67, 67, -25, 11, 
10, 67, 67, 67, 67, -25, 11), y = c(126, -29, -37, -63, -76, 
-70, -58, 23, -17, -26, -74, -72, -70, -73, 6, -24, -10, -54, 
-67, -59, -59, 27, -37, -12, -51, -69, -61, -58, 52, -52, -25, 
-46, -64, -54, -55, 41, -11, -22, -48, -63, -57, -56, 34, 17, 
56, -26, -13, -16, -25, 99, -39, -16, -54, -74, -52, -60, 9, 
-32, -17, -62, -66, -50, -65, 60, -34, -24, -62, -76, -62, -58, 
27, -36)), row.names = c(NA, -72L), class = "data.frame")

ggplot(df) + geom_point(aes(x, y)) + geom_smooth(aes(x, y))

幾何平滑的單調看起來還可以

第二個示例看起來並不單調:

df <- structure(list(x = c(33, -14, -14, -15, -10, -33, 2, 28, -33, 
-33, -33, -33, -48, -22, 0, 33, 33, 33, 33, 3, 37, 75, 17, 17, 
17, 17, 8, 95, 151, 67, 67, 67, 67, 31, 95, 151, 67, 67, 67, 
67, 31, 95, 151, 67, 67, 67, 67, 31, 95, 151, 67, 67, 67, 67, 
31, 95, 151, 67, 67, 67, 67, 31, 95, 139, 50, 50, 50, 50, 16, 
56, 101, 33), y = c(-50, 75, 77, 137, 36, 97, -42, -67, 147, 
163, 176, 132, 384, 100, 65, -17, -53, -11, -49, -48, -77, -87, 
-25, -23, -11, 4, -45, -54, -81, -36, -19, 3, -26, -6, -68, -74, 
-11, -21, 32, -28, -19, -41, -74, -36, -33, 47, -4, -35, -52, 
-69, -8, 47, 0, -45, 26, -48, -71, 19, 14, 18, -40, -71, -44, 
-61, 19, 5, -16, 15, 29, -48, -72, 0)), row.names = c(NA, -72L
), class = c("tbl_df", "tbl", "data.frame"))

ggplot(df) + geom_point(aes(x, y)) + geom_smooth(aes(x, y))

在此處輸入圖片說明

您可以看到函數下降,然后在x = 25 to 65之間上升,然后再次下降。 那不好-函數永遠不需要隨着x的增加而上升。

我還嘗試將nls()與單調遞減函數一起使用,例如nls() y ~ 1/xy ~ exp(1/x)但是由於我有成千上萬個數據集,因此未能找到有效的自動查找起始值的方法。 geom_smooth在許多情況下似乎工作得很好,除了第二個示例中發生顛簸的情況。

如果您只想要漂亮的曲線,則可以使用以下方法:

library(tidyverse)

df <- structure(list(x = c(33, -14, -14, -15, -10, -33, 2, 28, -33, 
                           -33, -33, -33, -48, -22, 0, 33, 33, 33, 33, 3, 37, 75, 17, 17, 
                           17, 17, 8, 95, 151, 67, 67, 67, 67, 31, 95, 151, 67, 67, 67, 
                           67, 31, 95, 151, 67, 67, 67, 67, 31, 95, 151, 67, 67, 67, 67, 
                           31, 95, 151, 67, 67, 67, 67, 31, 95, 139, 50, 50, 50, 50, 16, 
                           56, 101, 33), y = c(-50, 75, 77, 137, 36, 97, -42, -67, 147, 
                                               163, 176, 132, 384, 100, 65, -17, -53, -11, -49, -48, -77, -87, 
                                               -25, -23, -11, 4, -45, -54, -81, -36, -19, 3, -26, -6, -68, -74, 
                                               -11, -21, 32, -28, -19, -41, -74, -36, -33, 47, -4, -35, -52, 
                                               -69, -8, 47, 0, -45, 26, -48, -71, 19, 14, 18, -40, -71, -44, 
                                               -61, 19, 5, -16, 15, 29, -48, -72, 0)), row.names = c(NA, -72L
                                               ), class = c("tbl_df", "tbl", "data.frame"))
plot = ggplot(df) + 
  geom_point(aes(x, y)) + 
  geom_smooth(aes(x, y),
              method = "lm",
              formula = y ~ log(x-min(df$x)-1),
              se = FALSE)

print(plot)

在此處輸入圖片說明

由於您的值為負值,我只是以一種不穩定的方式強加了一條對數回歸線,但至少出現了一條漂亮的曲線...

對於后代,請檢查包裝騙局中形狀受約束的附加模型。

library(ggplot2)
library(scam)

df <- structure(list(x = c(33, -14, -14, -15, -10, -33, 2, 28, -33, 
    -33, -33, -33, -48, -22, 0, 33, 33, 33, 33, 3, 37, 75, 17, 17, 
    17, 17, 8, 95, 151, 67, 67, 67, 67, 31, 95, 151, 67, 67, 67, 
    67, 31, 95, 151, 67, 67, 67, 67, 31, 95, 151, 67, 67, 67, 67, 
    31, 95, 151, 67, 67, 67, 67, 31, 95, 139, 50, 50, 50, 50, 16, 
    56, 101, 33), y = c(-50, 75, 77, 137, 36, 97, -42, -67, 147, 
        163, 176, 132, 384, 100, 65, -17, -53, -11, -49, -48, -77, -87, 
        -25, -23, -11, 4, -45, -54, -81, -36, -19, 3, -26, -6, -68, -74, 
        -11, -21, 32, -28, -19, -41, -74, -36, -33, 47, -4, -35, -52, 
        -69, -8, 47, 0, -45, 26, -48, -71, 19, 14, 18, -40, -71, -44, 
        -61, 19, 5, -16, 15, 29, -48, -72, 0)), row.names = c(NA, -72L
        ), class = c("tbl_df", "tbl", "data.frame"))

如果您非常關注樣條線的形狀,則公式將需要進行一些修補,但是當您將樣條線定義為單調遞減( "mpd" )時,此方法將始終創建單調遞減擬合。

# for some reason an object called `weight` needs 
# to be present at ggplot2_3.1.1
weight <- rep(1, times = nrow(df))
ggplot(df, mapping = aes(x, y)) + 
    geom_point() + 
    geom_smooth(method = "scam", 
        # b-spline monotonic deceasing
        # see ?shape.constrained.smooth.terms
        formula = y ~ s(x, k = 5, bs = "mpd"), 
        se = FALSE)

在此處輸入圖片說明

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM