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.110 0.204 4.316
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.066072 seconds (6 allocations: 14.607 MiB, 9.44% 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) Welcome! Rulia has initialized julia inside R 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.050 0.012 0.062 R> system.time(R(jl_premier(10000000L))) utilisateur système écoulé 0.071 0.000 0.071
►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: 0x5630da47a058> <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.20707765391879152 julia> rand(2) 2-element Vector{Float64}: 0.32300331348711775 0.0003750199598218096 julia> rand(1:10) 5 julia> rand(1:10,2) 2-element Vector{Int64}: 7 3 julia> rand(1:10,2,2) 2×2 Matrix{Int64}: 7 9 1 3 julia> rand(1:10,2,2,2) 2×2×2 Array{Int64, 3}: [:, :, 1] = 3 2 4 6 [:, :, 2] = 10 6 3 3 julia> rand(1:10, (2,2)) 2×2 Matrix{Int64}: 9 6 3 6 julia> rand(1:10, (2,2,2)) 2×2×2 Array{Int64, 3}: [:, :, 1] = 9 3 3 2 [:, :, 2] = 9 3 9 9 julia> rand(Int,2) 2-element Vector{Int64}: 5322580483104314034 634686149610308863 julia> rand(Int8,2) 2-element Vector{Int8}: 69 12 julia> rand(Bool,2) 2-element Vector{Bool}: 1 0 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.5554818915930329 julia> rand(Normal(),2) 2-element Vector{Float64}: 0.4083472889711956 -1.4865193695018533 julia> rand(Normal(),2,2) 2×2 Matrix{Float64}: -0.885256 -0.259648 -0.853749 -0.311189 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] *(r::Regex) @ Base regex.jl:843 [2] *(x::Bool, z::Complex{Bool}) @ Base complex.jl:312 [3] *(x::Bool, y::Bool) @ Base bool.jl:168 [4] *(x::Bool, y::AbstractIrrational) @ Base irrationals.jl:166 [5] *(x::Bool, z::Complex) @ Base complex.jl:319 julia> length(methods(*)) 382
►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: 0x5630d8a58af8> <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, y) @ none:1 [2] Point(x::Float64, y::Float64) @ none:2 [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 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> 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 225 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 228 methods) julia> -(p::Point, p2::Point) = p + -p2 - (generic function with 229 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.3192903 0.3713584 0.2673476 R> Rzz <- R(zz) # objet jlvalue téléguidant l'objet zz de R R> Rzz 3-element Vector{Float64}: 0.3192903420422226 0.3713583564385772 0.26734759751707315 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.3713583564385772 0.26734759751707315 R> zz # Incroyable mais vrai! [1] 2.0000000 0.3713584 0.2673476 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.0000000 0.3713584 0.2673476 R> Rzz # la preuve: le vecteur Julia n'est pas modifié! 3-element Vector{Float64}: 2.0 0.3713583564385772 0.26734759751707315
►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.9708193 TRUE 2 0.8235548 FALSE 3 0.3087324 TRUE julia> @rget df 3×2 DataFrame Row │ a b │ Float64 Bool ─────┼───────────────── 1 │ 0.970819 true 2 │ 0.823555 false 3 │ 0.308732 true julia> df.a[2]=1 1 julia> df 3×2 DataFrame Row │ a b │ Float64 Bool ─────┼───────────────── 1 │ 0.970819 true 2 │ 1.0 false 3 │ 0.308732 true julia> @rput df 3×2 DataFrame Row │ a b │ Float64 Bool ─────┼───────────────── 1 │ 0.970819 true 2 │ 1.0 false 3 │ 0.308732 true julia> R"df" RCall.RObject{RCall.VecSxp} a b 1 0.9708193 TRUE 2 1.0000000 FALSE 3 0.3087324 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.970819 1 2 │ 1.0 0 3 │ 0.308732 1 julia> Main.d 3×2 DataFrame Row │ a b │ Float64 Int32 ─────┼───────────────── 1 │ 0.970819 1 2 │ 1.0 0 3 │ 0.308732 1 julia> df 3×2 DataFrame Row │ a b │ Float64 Bool ─────┼───────────────── 1 │ 0.970819 true 2 │ 1.0 false 3 │ 0.308732 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.9708193 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.