Skip to content

Commit

Permalink
add sapply
Browse files Browse the repository at this point in the history
  • Loading branch information
mingsnu committed Sep 18, 2016
1 parent 1522193 commit 6506570
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 17 deletions.
15 changes: 0 additions & 15 deletions src/List.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,6 @@ function Base.map(f::Function, d::AbstractList)
res
end

"""
lapply(d, f, args...; kwargs)
Apply a function on List `d`. `args` and `kwargs` will be passed to `f`.
#Example
```
d=as_list(Any[rand(i) for i in 1:10])
lapply(d, mean)
```
"""
function lapply(d::AbstractList, f::Function, args...; kwargs...)
map(x->f(x, args...; kwargs...), d)
end

"""
unlist(d, recursive::Bool)
Expand Down
4 changes: 2 additions & 2 deletions src/RFlavor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export rep, rep_len,
duplicated,
findinterval,
matrix,
List, list, unlist, lapply, as_list, rename!, rename,
List, list, unlist, lapply, sapply, as_list, rename!, rename,
seq,
setequal,
sweep
Expand All @@ -46,5 +46,5 @@ include("seq.jl")
include("setequal.jl")
include("sweep.jl")
include("Factor.jl")

include("apply.jl")
end # module
59 changes: 59 additions & 0 deletions src/apply.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"""
lapply(d, f, args...; kwargs)
Apply a function on List `d`. `args` and `kwargs` will be passed to `f`.
#Example
```
d=as_list(Any[rand(i) for i in 1:10])
lapply(d, mean)
```
"""
function lapply(d::AbstractList, f::Function, args...; kwargs...)
map(x->f(x, args...; kwargs...), d)
end


"""
sapply(d, f, args...; kwargs)
A user-friendly version and wrapper of `lapply` by default returning an array.
#Example
```
x = list(a=1:10, beta=exp(-3:3), logic = [true,false, false, true])
y = list(a = 1:5, b = log(1:5), c = rand(5))
z = list(a = ["a", "b", "c"], b = ["d", "e", "f"])
sapply(x, mean)
sapply(y, x->outer(x, x))
sapply(z, x->outer(x, x))
```
"""
function sapply(d::AbstractList, f::Function, args...;simplify = true, kwargs...)
l = lapply(d, f, args...; kwargs...)
if simplify && length(l) > 0
n = length(l)
## chceck whether types of all list elements are the same or not
tp = lapply(l, typeof)
for i in 2:n
is(tp[1], tp[i]) || return l
end
## check whether lengths of all list elements are the same or not
len = lapply(l, length)
for i in 2:n
is(len[1], len[i]) || return l
end
## if type and length are the same for all the list elements, convert to array
list_el_size = size(l[1])
list_el_len = prod(list_el_size)
list_el_len > 1 || return unlist(l)
v = Array(eltype(l[1]), list_el_len*n)
for i in 1:n
v[(list_el_len*(i-1) +1):list_el_len*i] = l[i][:]
end
return reshape(v, list_el_size..., n)
else
return l
end
end
9 changes: 9 additions & 0 deletions test/applytest.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
x = list(a=1:10, beta=exp(-3:3), logic = [true,false, false, true])
y = list(a = ["a", "b", "c"], b = ["d", "e", "f"])
@test unlist(RFlavor.lapply(x, mean)) == RFlavor.sapply(x, mean)
@test length(RFlavor.lapply(x, quantile, collect(1:3)/4)) == 3
@test size(RFlavor.sapply(x, quantile, collect(1:3)/4)) == (3, 3)
@test typeof(RFlavor.sapply(y, x->outer(x, x))) == Array{Any, 3}
## need `==` for List object
# RFlavor.lapply(x, x->outer(x, x)) == RFlavor.sapply(x, x->outer(x, x))

1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,4 @@ include("seqtest.jl")
include("others.jl")
include("astest.jl")
include("factortest.jl")
include("applytest.jl")

0 comments on commit 6506570

Please sign in to comment.