Próbuję zrobić wykres uderzeniowy (np. parallel coordinates, ale z ciągłą osią x), aby pokazać ranking w czasie. Mogę zrobić wykres liniową bardzo łatwo:Użyj zakrzywionych linii na wykresie wypukłości
library(ggplot2)
set.seed(47)
df <- as.data.frame(as.table(replicate(8, sample(4))), responseName = 'rank')
df$Var2 <- as.integer(df$Var2)
head(df)
#> Var1 Var2 rank
#> 1 A 1 4
#> 2 B 1 2
#> 3 C 1 3
#> 4 D 1 1
#> 5 A 2 3
#> 6 B 2 4
ggplot(df, aes(Var2, rank, color = Var1)) + geom_line() + geom_point()
wspaniałe. Teraz jednak chcę, aby linie łączące były zakrzywione. Pomimo tego, że nigdy nie ma więcej niż 1 y na x, geom_smooth
oferuje kilka możliwości. loess
wygląda na to, że powinien działać, ponieważ może zignorować punkty, z wyjątkiem najbliższych. Jednak nawet z szczypanie najlepszy mogę nadal zdobywa wiele punktów i przeregulowania innych, gdzie powinno być płaskie:
ggplot(df, aes(Var2, rank, color = Var1)) +
geom_smooth(method = 'loess', span = .7, se = FALSE) +
geom_point()
Próbowałem kilka innych splajnów, jak ggalt::geom_xspline
, ale wszystkie one nadal przekroczenia lub pominąć punkty:
ggplot(df, aes(Var2, rank, color = Var1)) + ggalt::geom_xspline() + geom_point()
Czy istnieje prosty sposób na krzywej te linie? Czy muszę zbudować własny splajn sigmoidalny? W celu wyjaśnienia, szukam czegoś podobnego D3.js's d3.curveMonotoneX
który trafia do każdego punktu i którego lokalne minimum i maksimum nie przekracza wartości Y:
Idealnie byłoby prawdopodobnie mają nachylenie 0 w każdym punkcie, też, ale to nie jest absolutnie konieczne.
Zgodnie z [ta odpowiedź] (https://stats.stackexchange.com/a/29442) - co pakiet 'cobs'? "COBS oznacza Constrained B-splines. Możliwe ograniczenia obejmują przechodzenie przez określone punkty, ustawianie pochodnych na określone wartości, monotoniczność (zwiększanie lub zmniejszanie), wklęsłość, wypukłość, periodyczność itd." Nie mogę od razu go uruchomić, ale jest obietnica. –
Ooh, to wygląda obiecująco. Próbowałem 'fda :: smooth.monotone', ale jego parametry są absurdalnie skomplikowane. – alistaire
Myślę, że możesz to zrobić z lessem, modyfikując stopień i rozpiętość 'geom_smooth (method = 'less", span = 0.3, se = FALSE, method.args = list (stopień = 1)) ' – user2957945