diff --git a/src/docstrings.jl b/src/docstrings.jl index 7a08f6bc..28b115e3 100644 --- a/src/docstrings.jl +++ b/src/docstrings.jl @@ -532,6 +532,33 @@ julia> @chain df begin 4 │ d 4 14 1 11 5 │ e 5 15 1 11 ``` +Note that unlike dplyr, @mutate transformations cannot be applied progressively-meaning you cannot reuse variables within the same @mutate call. This requires the use of separate @mutate calls. +``` +julia> @chain df begin + #= + it's tempting to do this: + + @mutate begin + b2 = b * 2 + b3 = b2 * 2 + end + + but this syntactic sugar isn't supported. + use separate @mutate calls instead. + =# + @mutate b2 = b * 2 + @mutate b3 = b2 * 2 + end +5×5 DataFrame + Row │ a b c b2 b3 + │ Char Int64 Int64 Int64 Int64 +─────┼────────────────────────────────── + 1 │ a 1 11 2 4 + 2 │ b 2 12 4 8 + 3 │ c 3 13 6 12 + 4 │ d 4 14 8 16 + 5 │ e 5 15 10 20 +``` """ const docstring_summarize = diff --git a/test/runtests.jl b/test/runtests.jl index 0b299eb1..de6f2ebb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -22,4 +22,5 @@ test_df = DataFrame( @testset "TidierData" verbose = true begin include("test_pivots.jl") + include("test_mutate.jl") end diff --git a/test/test_mutate.jl b/test/test_mutate.jl new file mode 100644 index 00000000..1f536a90 --- /dev/null +++ b/test/test_mutate.jl @@ -0,0 +1,41 @@ +@testset "@mutate()" verbose = true begin + + @testset "empty mutate returns input" begin + df = DataFrame(x = 1) + gf = @group_by(df, x) + + @test isequal(@mutate(df), df) + @test isequal(@mutate(gf), gf) + + + @test isequal(@mutate(df, []), df) + @test isequal(@mutate(gf, []), gf) + end + + @testset "length-1 vectors are recycled" begin + df = DataFrame(x = 1:4) + @test isequal(@mutate(df, y = 1)[!, :y], fill(1, 4)) + @test_throws "ArgumentError: New columns must have the same length as old columns" @mutate(df, y = 1:2) + end + + @testset "mutate supports constants" begin + df = DataFrame(x = 1:10, g = repeat(1:2, inner = 5)) + y = 1:10 + z = 1:5 + + @test isequal(@mutate(df, y = !!y)[!, :y], y) + end + + @testset "mutate works on empty dataframes" begin + df = DataFrame() + res = @mutate(df) + @test isequal(nrow(res), 0) + @test isequal(ncol(res), 0) + + res = @mutate(df, x = Int64[]) + @test isequal(names(res), ["x"]) + @test isequal(nrow(res), 0) + @test isequal(ncol(res), 1) + end + +end