R vs Julia
Julia successeuse naturelle de R (😂 Adeline Joke)
R(ulia) Drouilhet
https://cqls.dyndoc.fr/RvsJulia
(ou /Cours
)
►Petit questionnaire de bienvenue sur les Types en R et Julia!
En R et Julia, on parle de Type d'objet. Ici on ne considère les Types d'objets s'enregistrant dans des variables.
►Points communs / Différences R vs Julia
►Comparer codes R et Julia
►Crible d'Ératosthène: nombres premiers
Retranscriptions R et Julia du code proposé sur wikipedia
Avec le package Rulia on peut directement faire du Julia dans le R et ainsi booster les performances (sans passer par Rcpp)
Crible d'Ératosthène en R
premier = function(n) { l = rep(TRUE,n) l[1] = FALSE for(i in 2:sqrt(n)) { if(l[i]) { for(j in seq(i*i,n,by=i)) { l[j] = FALSE } } } return((1:n)[l]) # ou which(l) } premier(120) system.time(premier(10000000))
R> premier = function(n) { + l = rep(TRUE,n) + l[1] = FALSE + for(i in 2:sqrt(n)) { + if(l[i]) { + for(j in seq(i*i,n,by=i)) { + l[j] = FALSE + } + } + } + return((1:n)[l]) # ou which(l) + } R> premier(120) [1] 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 [20] 71 73 79 83 89 97 101 103 107 109 113 R> system.time(premier(10000000)) utilisateur système écoulé 4.098 0.116 4.216
Crible d'Ératosthène en Julia
function premier(n) # ou premier = function(n) l = fill(true,n) l[1] = false for i in 2:round(Int,sqrt(n)) if l[i] for j in i*i:i:n l[j] = false end end end return (1:n)[l] # ou findall(l) end premier(120) @time begin;premier(10000000);nothing;end
julia> function premier(n) # ou premier = function(n) l = fill(true,n) l[1] = false for i in 2:round(Int,sqrt(n)) if l[i] for j in i*i:i:n l[j] = false end end end return (1:n)[l] # ou findall(l) end premier (generic function with 1 method) julia> premier(120) 30-element Vector{Int64}: 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 101 103 107 109 113 julia> @time begin;premier(10000000);nothing;end 0.126929 seconds (6 allocations: 14.607 MiB, 51.81% gc time)
Crible d'Ératosthène en Rulia
require(Rulia) jl(` function premier(n) l = fill(true,n) l[1] = false for i in 2:round(Int,sqrt(n)) if l[i] for j in i*i:i:n l[j] = false end end end return (1:n)[l] end `) jl_premier <- jl(premier) R(jl_premier(120L)) system.time(jl_premier(10000000L)) system.time(R(jl_premier(10000000L)))
R> require(Rulia) R> jl(` + function premier(n) + l = fill(true,n) + l[1] = false + for i in 2:round(Int,sqrt(n)) + if l[i] + for j in i*i:i:n + l[j] = false + end + end + end + return (1:n)[l] + end + `) premier (generic function with 1 method) R> jl_premier <- jl(premier) R> R(jl_premier(120L)) [1] 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 [20] 71 73 79 83 89 97 101 103 107 109 113 R> system.time(jl_premier(10000000L)) utilisateur système écoulé 0.057 0.000 0.057 R> system.time(R(jl_premier(10000000L))) utilisateur système écoulé 0.079 0.012 0.090
►Le "dispatching (single and multiple)" en action
►"Single dispatching" du R vs "multiple dispatching" du Julia
Notons que par défaut le R utilise le mode S3 qui est du "single dispatching" équivalent en termes de programmation objet à du python.
Single dispatching S3 en R
summary methods(summary) str(summary.default) summary(1:10) # redirigé vers summary.default(1:10) summary(matrix(1:10,nr=2)) # redirigé vers summary.matrix(matrix(1:10,nr=2))
R> summary function (object, ...) UseMethod("summary") <bytecode: 0x564dcaa76c28> <environment: namespace:base> R> methods(summary) [1] summary.aov summary.aovlist* [3] summary.aspell* summary.check_packages_in_dir* [5] summary.connection summary.data.frame [7] summary.Date summary.default [9] summary.ecdf* summary.factor [11] summary.glm summary.infl* [13] summary.jlexception* summary.jlexceptions* [15] summary.lm summary.loess* [17] summary.manova summary.matrix [19] summary.mlm* summary.nls* [21] summary.packageStatus* summary.POSIXct [23] summary.POSIXlt summary.ppr* [25] summary.prcomp* summary.princomp* [27] summary.proc_time summary.srcfile [29] summary.srcref summary.stepfun [31] summary.stl* summary.table [33] summary.tukeysmooth* summary.warnings see '?methods' for accessing help and source code R> str(summary.default) function (object, ..., digits, quantile.type = 7) R> summary(1:10) # redirigé vers summary.default(1:10) Min. 1st Qu. Median Mean 3rd Qu. Max. 1.00 3.25 5.50 5.50 7.75 10.00 R> summary(matrix(1:10,nr=2)) # redirigé vers summary.matrix(matrix(1:10,nr=2)) V1 V2 V3 V4 V5 Min. :1.00 Min. :3.00 Min. :5.00 Min. :7.00 Min. : 9.00 1st Qu.:1.25 1st Qu.:3.25 1st Qu.:5.25 1st Qu.:7.25 1st Qu.: 9.25 Median :1.50 Median :3.50 Median :5.50 Median :7.50 Median : 9.50 Mean :1.50 Mean :3.50 Mean :5.50 Mean :7.50 Mean : 9.50 3rd Qu.:1.75 3rd Qu.:3.75 3rd Qu.:5.75 3rd Qu.:7.75 3rd Qu.: 9.75 Max. :2.00 Max. :4.00 Max. :6.00 Max. :8.00 Max. :10.00
- Le "multiple dispatching" existe en R avec le S4 (et un peu avec le nouveau S7) mais très limité (signature à nombre fixé d'arguments)
- Le "multiple dispatching" est le fondement du fonctionnement de Julia
Multiple dispatching: rand en Julia
rand() rand(2) rand(1:10) rand(1:10,2) rand(1:10,2,2) rand(1:10,2,2,2) rand(1:10, (2,2)) rand(1:10, (2,2,2)) rand(Int,2) rand(Int8,2) rand(Bool,2) [(typemin(T),typemax(T)) for T=(Int8,Int,Bool)] using Distributions rand(Normal()) rand(Normal(),2) rand(Normal(),2,2) ## exploring rand import Random length(methods(rand, Random)) length(methods(rand, Distributions))
julia> rand() 0.5882789414757903 julia> rand(2) 2-element Vector{Float64}: 0.6535751471259258 0.24497707942489866 julia> rand(1:10) 4 julia> rand(1:10,2) 2-element Vector{Int64}: 9 2 julia> rand(1:10,2,2) 2×2 Matrix{Int64}: 5 6 5 3 julia> rand(1:10,2,2,2) 2×2×2 Array{Int64, 3}: [:, :, 1] = 1 6 9 10 [:, :, 2] = 5 1 4 2 julia> rand(1:10, (2,2)) 2×2 Matrix{Int64}: 2 6 4 5 julia> rand(1:10, (2,2,2)) 2×2×2 Array{Int64, 3}: [:, :, 1] = 1 5 7 8 [:, :, 2] = 3 2 8 2 julia> rand(Int,2) 2-element Vector{Int64}: -7239707682465649319 -429825186516224282 julia> rand(Int8,2) 2-element Vector{Int8}: -71 12 julia> rand(Bool,2) 2-element Vector{Bool}: 0 1 julia> [(typemin(T),typemax(T)) for T=(Int8,Int,Bool)] 3-element Vector{Tuple{Integer, Integer}}: (-128, 127) (-9223372036854775808, 9223372036854775807) (false, true) julia> using Distributions julia> rand(Normal()) -0.40157031420476236 julia> rand(Normal(),2) 2-element Vector{Float64}: 1.54136115228539 -0.6603749257896785 julia> rand(Normal(),2,2) 2×2 Matrix{Float64}: -1.57258 -0.730296 0.266283 0.991521 julia> ## exploring julia> rand rand (generic function with 181 methods) julia> import Random julia> length(methods(rand, Random)) 76 julia> length(methods(rand, Distributions)) 104
►"Double dispatching" pour l'opérateur de multiplication
Echec single dispatching pour la multiplication en R
2 * 1:10 # ou `*`(2, 1:10) 1:10 * 1:10 # ou `*`(1:10, 1:10) 1:2 * t(1:2) t(t(1:2)) * t(1:2) 1:2 %*% t(1:2) # pas de multiple dispatching! t(t(1:2)) %*% t(1:2)
R> 2 * 1:10 # ou `*`(2, 1:10) [1] 2 4 6 8 10 12 14 16 18 20 R> 1:10 * 1:10 # ou `*`(1:10, 1:10) [1] 1 4 9 16 25 36 49 64 81 100 R> 1:2 * t(1:2) [,1] [,2] [1,] 1 4 R> t(t(1:2)) * t(1:2) Erreur dans t(t(1:2)) * t(1:2) : tableaux de tailles inadéquates R> 1:2 %*% t(1:2) # pas de multiple dispatching! [,1] [,2] [1,] 1 2 [2,] 2 4 R> t(t(1:2)) %*% t(1:2) [,1] [,2] [1,] 1 2 [2,] 2 4
Multiple dispatching: multiplication en Julia
v = collect(1:10) 2v 2(1:10) # ou *(2,1:10) 2 * 1:10 # ou (:)(2 * 1, 10) [1,2] * [1,2]' # ou [1,2] * transpose([1,2]) [1;2] * [1 2] # vcat(1,2) * hcat(1,2) A = [1 2; 3 4; 5 6] # ou vcat(hcat(1,2), hcat(3,4), hcat(5,6)) hvcat((2,2,2), 1,2,3,4,5,6) hvcat((2,2,2), 1:6...) 2A # ou 2*A ou 2 * A A * A' A' * A first(methods(*),5) length(methods(*))
julia> v = collect(1:10) 10-element Vector{Int64}: 1 2 3 4 5 6 7 8 9 10 julia> 2v 10-element Vector{Int64}: 2 4 6 8 10 12 14 16 18 20 julia> 2(1:10) # ou *(2,1:10) 2:2:20 julia> 2 * 1:10 # ou (:)(2 * 1, 10) 2:10 julia> [1,2] * [1,2]' # ou [1,2] * transpose([1,2]) 2×2 Matrix{Int64}: 1 2 2 4 julia> [1;2] * [1 2] # vcat(1,2) * hcat(1,2) 2×2 Matrix{Int64}: 1 2 2 4 julia> A = [1 2; 3 4; 5 6] # ou vcat(hcat(1,2), hcat(3,4), hcat(5,6)) 3×2 Matrix{Int64}: 1 2 3 4 5 6 julia> hvcat((2,2,2), 1,2,3,4,5,6) 3×2 Matrix{Int64}: 1 2 3 4 5 6 julia> hvcat((2,2,2), 1:6...) 3×2 Matrix{Int64}: 1 2 3 4 5 6 julia> 2A # ou 2*A ou 2 * A 3×2 Matrix{Int64}: 2 4 6 8 10 12 julia> A * A' 3×3 Matrix{Int64}: 5 11 17 11 25 39 17 39 61 julia> A' * A 2×2 Matrix{Int64}: 35 44 44 56 julia> first(methods(*),5) [1] *(::Missing, ::Missing) @ Base missing.jl:122 [2] *(::Missing) @ Base missing.jl:101 [3] *(d::Missing, x::Union{AbstractChar, AbstractString}) @ Base missing.jl:174 [4] *(::Missing, ::Number) @ Base missing.jl:123 [5] *(x::Bool, z::Complex{Bool}) @ Base complex.jl:312 julia> length(methods(*)) 374
►Programmation mode dispatching
Single dispatching: constructeur pour Point
Point = function(x = 0, y = 0) { obj <- list(x = x, y = y) class(obj) <- "Point" obj } print # fonction générique print.Point = function(obj, ...) { cat("Point(",obj$x, ",", obj$y,") ",sep="") } Point() # Affichage par défaut si print.Point pas défini. "default" peut être vue comme la classe "Any" de Julia print.default(Point())
R> Point = function(x = 0, y = 0) { + obj <- list(x = x, y = y) + class(obj) <- "Point" + obj + } R> print # fonction générique function (x, ...) UseMethod("print") <bytecode: 0x564dc7729348> <environment: namespace:base> R> print.Point = function(obj, ...) { + cat("Point(",obj$x, ",", obj$y,") ",sep="") + } R> Point() Point(0,0) R> # Affichage par défaut si print.Point pas défini. "default" peut être vue comme la classe "Any" de Julia R> print.default(Point()) $x [1] 0 $y [1] 0 attr(,"class") [1] "Point"
Multiple dispatching: constructeur implicite pour Point
mutable struct Point x::Float64 y::Float64 end Point(1.0, 2.0) # Constructeur implicite ## Nouveau constructeur avec arguments nommés avec valeurs par défaut Point(; x = 0.0, y = 0.0) = Point(x, y) Point() Point(y=2.0) methods(Point) Point(y=2) Point(1//2, 3//4) Point(1//2, 3)
julia> mutable struct Point x::Float64 y::Float64 end julia> julia> Point(1.0, 2.0) # Constructeur implicite Point(1.0, 2.0) julia> julia> ## Nouveau constructeur avec arguments nommés avec valeurs par défaut julia> Point(; x = 0.0, y = 0.0) = Point(x, y) Point julia> julia> Point() Point(0.0, 0.0) julia> Point(y=2.0) Point(0.0, 2.0) julia> methods(Point) # 3 methods for type constructor: [1] Point(x::Float64, y::Float64) @ none:2 [2] Point(; x, y) @ none:1 [3] Point(x, y) @ none:2 julia> Point(y=2) Point(0.0, 2.0) julia> Point(1//2, 3//4) Point(0.5, 0.75) julia> Point(1//2, 3) Point(0.5, 3.0)
Single dispatching: méthodes pour Point
# Nouvelle fonction générique translate = function(obj, ...) UseMethod("translate") # Méthode par défaut (comme la classe "Any" de Julia) translate.default = function(obj, ...) cat("rien à faire ") # Méthode spécifique à la classe Point translate.Point = function(obj, x, y) { if(missing(y)) { if(inherits(x, "Point")) Point(obj$x + x$x, obj$y + x$y) else Point(obj$x + x[1], obj$y + x[2]) } else Point(obj$x + x, obj$y + y) } p = Point(1,2) translate(p, p) translate(p, 2, 1) translate(p, c(3,2))
R> # Nouvelle fonction générique R> translate = function(obj, ...) UseMethod("translate") R> # Méthode par défaut (comme la classe "Any" de Julia) R> translate.default = function(obj, ...) cat("rien à faire ") R> # Méthode spécifique à la classe Point R> translate.Point = function(obj, x, y) { + if(missing(y)) { + if(inherits(x, "Point")) + Point(obj$x + x$x, obj$y + x$y) + else + Point(obj$x + x[1], obj$y + x[2]) + } else + Point(obj$x + x, obj$y + y) + } R> p = Point(1,2) R> translate(p, p) Point(2,4) R> translate(p, 2, 1) Point(3,3) R> translate(p, c(3,2)) Point(4,4)
Multiple dispatching: méthodes pour Point
## Nouvelles méthodes! La fonction générique "translate" est créée dès la création de la première méthode (Pas de UseMethod comme en R!) translate(p::Point, x::Float64, y::Float64) = Point(p.x + x, p.y + y) translate(p::Point, p2::Point) = translate(p, p2.x, p2.y) translate(p::Point, p2::Tuple{Float64, Float64}) = translate(p, p2[1], p2[2]) translate(p::Point, p2::Vector{Float64}) = translate(p, p2[1], p2[2]) translate p = Point(1.0, 2.0) translate(p, p) translate(p, 2.0, 1.0) translate(p, (3.0, 2.0)) translate(p, [3.0, 2.0]) translate!(p::Point, x::Float64, y::Float64) = p.x, p.y = p.x + x, p.y + y translate!(p::Point, p2::Point) = translate!(p, p2.x, p2.y) translate!(p::Point, p2::Tuple{Float64, Float64}) = translate!(p, p2[1], p2[2]) translate!(p::Point, p2::Vector{Float64}) = translate!(p, p2[1], p2[2]) translate!(p, (0.5, 0.5)) p
julia> ## Nouvelles méthodes! La fonction générique "translate" est créée dès la création de la première méthode (Pas de UseMethod comme en R!) julia> translate(p::Point, x::Float64, y::Float64) = Point(p.x + x, p.y + y) translate (generic function with 4 methods) julia> translate(p::Point, p2::Point) = translate(p, p2.x, p2.y) translate (generic function with 4 methods) julia> translate(p::Point, p2::Tuple{Float64, Float64}) = translate(p, p2[1], p2[2]) translate (generic function with 4 methods) julia> translate(p::Point, p2::Vector{Float64}) = translate(p, p2[1], p2[2]) translate (generic function with 4 methods) julia> translate translate (generic function with 4 methods) julia> julia> p = Point(1.0, 2.0) Point(1.0, 2.0) julia> translate(p, p) Point(2.0, 4.0) julia> translate(p, 2.0, 1.0) Point(3.0, 3.0) julia> translate(p, (3.0, 2.0)) Point(4.0, 4.0) julia> translate(p, [3.0, 2.0]) Point(4.0, 4.0) julia> julia> translate!(p::Point, x::Float64, y::Float64) = p.x, p.y = p.x + x, p.y + y translate! (generic function with 1 method) julia> translate!(p::Point, p2::Point) = translate!(p, p2.x, p2.y) translate! (generic function with 2 methods) julia> translate!(p::Point, p2::Tuple{Float64, Float64}) = translate!(p, p2[1], p2[2]) translate! (generic function with 3 methods) julia> translate!(p::Point, p2::Vector{Float64}) = translate!(p, p2[1], p2[2]) translate! (generic function with 4 methods) julia> julia> translate!(p, (0.5, 0.5)) (1.5, 2.5) julia> p Point(1.5, 2.5)
Multiple dispatching: + et - pour Point
UnionPoint = Union{Point, Tuple{Float64, Float64}, Vector{Float64}} import Base.+ +(p::Point, p2::UnionPoint) = translate(p, p2) p + p p + [3.0, 2.0] p2 = p + (3.0, 2.0) import Base.- -(p::Point) = Point(-p.x, -p.y) -(p::Point, p2::Point) = p + -p2 -p p2 - p
julia> UnionPoint = Union{Point, Tuple{Float64, Float64}, Vector{Float64}} Union{Tuple{Float64, Float64}, Point, Vector{Float64}} julia> import Base.+ julia> +(p::Point, p2::UnionPoint) = translate(p, p2) + (generic function with 266 methods) julia> p + p Point(3.0, 5.0) julia> p + [3.0, 2.0] Point(4.5, 4.5) julia> p2 = p + (3.0, 2.0) Point(4.5, 4.5) julia> import Base.- julia> -(p::Point) = Point(-p.x, -p.y) - (generic function with 239 methods) julia> -(p::Point, p2::Point) = p + -p2 - (generic function with 239 methods) julia> -p Point(-1.5, -2.5) julia> p2 - p Point(3.0, 2.0)
►Calcul vectoriel (broadcasting en Julia) et Boucle for
Exemple de Loi conditionnelle: $n$ réalisations de $Y \leadsto \mathcal{N}(X, 1.5)$ sachant que $X\leadsto \mathcal{N}(3,2)$
En R, c'est direct par vectorisation.
La forme la plus ressemblante en Julia utilise la notion de "broadcasting" (diffusion/vectorisation par une boucle for sur l'expression)
A la différence du R, on peut définir l'objet "la loi de probabilité" et ici celle du vecteur aléatoire $\mathbf{X}$
En R, c'est direct par vectorisation.
Loi conditionnelle en R
n = 10 x = rnorm(n,3,2) (yx = rnorm(n,x,1.5))
R> n = 10 R> x = rnorm(n,3,2) R> (yx = rnorm(n,x,1.5)) [1] 4.6911403 3.6606581 1.0514205 3.9437504 4.1594289 3.8937451 [7] -0.1050789 2.5849682 5.6847011 0.6243298
Loi conditionnelle en Julia
using Distributions n = 10 x = rand(Normal(3,2), n); y = rand.(Normal.(x,1.5)) # ou @. rand(Normal(x,1.5))
julia> using Distributions julia> n = 10 10 julia> x = rand(Normal(3,2), n); julia> y = rand.(Normal.(x,1.5)) # ou @. rand(Normal(x,1.5)) 10-element Vector{Float64}: 4.3691573653609685 0.5061521810820693 5.023327765029702 -1.0644152780783798 1.8618761731117683 2.2987525186700073 3.5866333911247557 6.166501095037341 1.5483673051275924 9.473727504698621
Loi conditionnelle en Julia
X = fill(Normal(3,2), n) typeof(X) y = rand.(Normal.(rand.(X),1.5)) # ou @. rand(Normal(rand(X),1.5)) # ou en 2 étapes Y = Normal.(rand.(X),1.5) y = rand.(Y)
julia> X = fill(Normal(3,2), n) 10-element Vector{Distributions.Normal{Float64}}: Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) Distributions.Normal{Float64}(μ=3.0, σ=2.0) julia> typeof(X) Vector{Normal{Float64}} (alias for Array{Distributions.Normal{Float64}, 1}) julia> y = rand.(Normal.(rand.(X),1.5)) # ou @. rand(Normal(rand(X),1.5)) 10-element Vector{Float64}: 1.3941085198770744 2.7192930223714 0.966705431832747 5.074318911443579 -1.4413798997037692 4.895348542891374 2.358984038323269 -1.7661197129708746 3.098856831740648 5.069847427647938 julia> # ou en 2 étapes julia> Y = Normal.(rand.(X),1.5) 10-element Vector{Distributions.Normal{Float64}}: Distributions.Normal{Float64}(μ=-0.19821719430184226, σ=1.5) Distributions.Normal{Float64}(μ=11.249372225280048, σ=1.5) Distributions.Normal{Float64}(μ=2.9489364565045837, σ=1.5) Distributions.Normal{Float64}(μ=4.674577816261513, σ=1.5) Distributions.Normal{Float64}(μ=2.9143918934477893, σ=1.5) Distributions.Normal{Float64}(μ=5.512650813670501, σ=1.5) Distributions.Normal{Float64}(μ=5.218877744970909, σ=1.5) Distributions.Normal{Float64}(μ=0.14546007977953312, σ=1.5) Distributions.Normal{Float64}(μ=3.4661222013560575, σ=1.5) Distributions.Normal{Float64}(μ=4.978873166711072, σ=1.5) julia> y = rand.(Y) 10-element Vector{Float64}: -3.048105785355899 13.119980373544985 2.734517638313852 2.0835106794557112 0.7252625628526845 6.5063677295833005 5.59264708455326 0.41890196421942744 4.295117291153683 5.6891671290643835
Loi conditionnelle en Julia
x = [rand(Normal(3,2)) for _ = 1:n] y = [rand(Normal(μ,1.5)) for μ = x]
julia> x = [rand(Normal(3,2)) for _ = 1:n] 10-element Vector{Float64}: 5.486825414938051 2.261761823098594 1.4846492888104867 7.044394613077319 1.281850478676397 3.2630895154489066 2.7145054624247154 2.2046027879392103 5.906943017128002 4.344413599423314 julia> y = [rand(Normal(μ,1.5)) for μ = x] 10-element Vector{Float64}: 7.602292431916963 0.9660483510330454 3.2605509617171045 6.0254805723967495 1.9329095166559684 1.5834633916386265 2.5170618150515245 2.2950961996405903 5.268945466334383 4.016849673107867
Loi conditionnelle en Julia
X = (rand(Normal(3,2)) for _ = 1:n) typeof(X) Y = (rand(Normal(μ,1.5)) for μ = X) typeof(Y) ## collecter Y sans collecter X collect(Y)
julia> X = (rand(Normal(3,2)) for _ = 1:n) Base.Generator{UnitRange{Int64}, var"#256#257"}(var"#256#257"(), 1:10) julia> typeof(X) Base.Generator{UnitRange{Int64}, var"#256#257"} julia> Y = (rand(Normal(μ,1.5)) for μ = X) Base.Generator{Base.Generator{UnitRange{Int64}, var"#256#257"}, var"#258#259"}(var"#258#259"(), Base.Generator{UnitRange{Int64}, var"#256#257"}(var"#256#257"(), 1:10)) julia> typeof(Y) Base.Generator{Base.Generator{UnitRange{Int64}, var"#256#257"}, var"#258#259"} julia> julia> ## collecter Y sans collecter X julia> collect(Y) 10-element Vector{Float64}: 0.36598255041965133 0.056476763014507825 -1.4058160282091028 7.581087542164001 3.729931473460135 1.494252705721596 -0.19482716134946135 4.120843632457409 6.262488775048499 -3.212067290859674
Loi conditionnelle en Julia
x = rand(Normal(3,2), n); y = map(μ -> rand(Normal(μ,1.5)), x) y = map(x) do μ rand(Normal(μ,1.5)) end
julia> x = rand(Normal(3,2), n); julia> y = map(μ -> rand(Normal(μ,1.5)), x) 10-element Vector{Float64}: 2.113481454861714 1.8611618369875949 5.092415834624551 3.984896847207592 5.110478382725282 2.62996639917499 5.128376399454387 6.162332288291868 -2.100658906623645 -1.0296920774882596 julia> y = map(x) do μ rand(Normal(μ,1.5)) end 10-element Vector{Float64}: 1.560500334409705 1.3511762341284266 2.2918705087279587 -1.1834732812720539 5.775746096256306 3.944169659915564 7.1298611490346016 7.1893107744323235 -0.8169989537898281 -0.41147178792342576
Loi conditionnelle en Julia
x = rand(Normal(3,2), n); y = similar(x) for i in eachindex(x) y[i] = rand(Normal(x[i],1.5)) end y
julia> x = rand(Normal(3,2), n); julia> y = similar(x) 10-element Vector{Float64}: 6.9299236202998e-310 6.9299236202998e-310 6.9299236202998e-310 6.9299236202998e-310 6.92992362054923e-310 6.92992362074844e-310 6.9299236213018e-310 6.92992362134606e-310 6.92992362077057e-310 6.9299236207927e-310 julia> for i in eachindex(x) y[i] = rand(Normal(x[i],1.5)) end julia> y 10-element Vector{Float64}: 1.7274647978171687 -1.428240441148426 1.6846484616905288 5.735829961165866 4.689577124104667 3.4756394074216574 0.523175867161167 6.573749377021547 10.147360359449232 6.111318615806665
►R et Julia en résumé
►Rulia une tentative de remplacer Rcpp
►Interactions entre R et Julia
►Julia dans R avec Rulia
Rulia
require(Rulia) jlinclude(Rulia::RCall) zz <- runif(3) zz Rzz <- R(zz) # objet jlvalue téléguidant l'objet zz de R Rzz jl(typeof)(Rzz) # reconnu en Julia comme un véritable vecteur Rzz[1] <- 2 Rzz zz # Incroyable mais vrai! zz[1] <- 1 # en R, un nouveau vecteur est créé! zz # les vecteurs en R sont statiques à la différence de Julia Rzz # la preuve: le vecteur Julia n'est pas modifié!
R> require(Rulia) R> jlinclude(Rulia::RCall) R> zz <- runif(3) R> zz [1] 0.94396580 0.42768618 0.03775241 R> Rzz <- R(zz) # objet jlvalue téléguidant l'objet zz de R R> Rzz 3-element Vector{Float64}: 0.9439658001065254 0.4276861846446991 0.03775241179391742 R> jl(typeof)(Rzz) # reconnu en Julia comme un véritable vecteur Vector{Float64} (alias for Array{Float64, 1}) R> Rzz[1] <- 2 R> Rzz 3-element Vector{Float64}: 2.0 0.4276861846446991 0.03775241179391742 R> zz # Incroyable mais vrai! [1] 2.00000000 0.42768618 0.03775241 R> zz[1] <- 1 # en R, un nouveau vecteur est créé! R> zz # les vecteurs en R sont statiques à la différence de Julia [1] 1.00000000 0.42768618 0.03775241 R> Rzz # la preuve: le vecteur Julia n'est pas modifié! 3-element Vector{Float64}: 2.0 0.4276861846446991 0.03775241179391742
►R dans Julia avec RCall.jl
RCall.jl
using RCall R""" df <- data.frame(a=runif(3),b=TRUE) df$b[2] <- FALSE df """ @rget df df.a[2]=1 df @rput df R"df" R""" require(Rulia) jlinclude(Rulia::RCall) jl(d=R(df)) jl()$d """ Main.d df # Un peu de Magie! Modification de d en Julia Main.d.a[3] = 5 # Et Abracadabra! Modification de la data.frame alors que R est un langage statique R"df"
julia> using RCall julia> R""" df <- data.frame(a=runif(3),b=TRUE) df$b[2] <- FALSE df """ RCall.RObject{RCall.VecSxp} a b 1 0.3977069 TRUE 2 0.1661558 FALSE 3 0.1662044 TRUE julia> @rget df 3×2 DataFrame Row │ a b │ Float64 Bool ─────┼───────────────── 1 │ 0.397707 true 2 │ 0.166156 false 3 │ 0.166204 true julia> df.a[2]=1 1 julia> df 3×2 DataFrame Row │ a b │ Float64 Bool ─────┼───────────────── 1 │ 0.397707 true 2 │ 1.0 false 3 │ 0.166204 true julia> @rput df 3×2 DataFrame Row │ a b │ Float64 Bool ─────┼───────────────── 1 │ 0.397707 true 2 │ 1.0 false 3 │ 0.166204 true julia> R"df" RCall.RObject{RCall.VecSxp} a b 1 0.3977069 TRUE 2 1.0000000 FALSE 3 0.1662044 TRUE julia> R""" require(Rulia) jlinclude(Rulia::RCall) jl(d=R(df)) jl()$d """ RCall.RObject{RCall.ExtPtrSxp} 3×2 DataFrame Row │ a b │ Float64 Int32 ─────┼───────────────── 1 │ 0.397707 1 2 │ 1.0 0 3 │ 0.166204 1 julia> Main.d 3×2 DataFrame Row │ a b │ Float64 Int32 ─────┼───────────────── 1 │ 0.397707 1 2 │ 1.0 0 3 │ 0.166204 1 julia> df 3×2 DataFrame Row │ a b │ Float64 Bool ─────┼───────────────── 1 │ 0.397707 true 2 │ 1.0 false 3 │ 0.166204 true julia> # Un peu de Magie! Modification de d en Julia julia> Main.d.a[3] = 5 5 julia> # Et Abracadabra! Modification de la data.frame alors que R est un langage statique julia> R"df" RCall.RObject{RCall.VecSxp} a b 1 0.3977069 TRUE 2 1.0000000 FALSE 3 5.0000000 TRUE
WebR Console
Introduction
Taper votre code R dans l'éditeur de texte du bas, exécuter-le et voir la sortie dédiée:
- Editeur de texte du haut pour l'obtention des résultats
- Plot dans la partie de droite
Exécuter code
Click sur
ou [Ctrl] + [R]
Effacer toutes les sorties
Click sur
Effacer la première sortie
Click sur
Sélection Jeu de données
Sélectionner un jeu de données dans le menu déroulant
Une fois sélectionné le jeu de données est exécuté dans la console WebR.