diff --git a/src/abstractdataframe/selection.jl b/src/abstractdataframe/selection.jl index 9782163e4..43e4ab7f4 100644 --- a/src/abstractdataframe/selection.jl +++ b/src/abstractdataframe/selection.jl @@ -1820,22 +1820,27 @@ function manipulate(dfv::SubDataFrame, @nospecialize(args...); copycols::Bool, k else # we do not support transformations here # newinds contains only indexing; making it Vector{Any} avoids some compilation - newinds = [] + newinds = Any[] seen_single_column = Set{Int}() for ind in args + if ind isa Pair || ind isa AbstractVecOrMat{<:Pair} + throw(ArgumentError( + "Transformations are not supported for SubDataFrame with copycols=false. " * + "Only column selection is allowed." + )) + end + ind_idx = index(dfv)[ind] if ind isa ColumnIndex - ind_idx = index(dfv)[ind] if ind_idx in seen_single_column - throw(ArgumentError("selecting the same column multiple times " * - "using Symbol, string or integer is not allowed " * - "($ind was passed more than once")) - else - push!(seen_single_column, ind_idx) + throw(ArgumentError( + "selecting the same column multiple times " * + "using Symbol, string or integer is not allowed " * + "($ind was passed more than once)" + )) end - else - newind = index(dfv)[ind] - push!(newinds, newind) + push!(seen_single_column, ind_idx) end + push!(newinds, ind_idx) end return view(dfv, :, Cols(newinds...)) end diff --git a/test/utils.jl b/test/utils.jl index 9ad18aa38..a6e4030d4 100644 --- a/test/utils.jl +++ b/test/utils.jl @@ -166,3 +166,33 @@ end end end # module + +@testset "SubDataFrame copycols=false rejects transformations" begin + df = DataFrame(a = [1, 2, 3]) + v = @view df[1:2, :] + + err = try + select(v, :a => ByRow(x -> x + 1) => :a; copycols=false) + catch e + e + end + + @test err isa ArgumentError + @test occursin("copycols=false", sprint(showerror, err)) +end + +@testset "SubDataFrame copycols=false column selection" begin + df = DataFrame(a = [1, 2, 3], b = [1, 2, 3]) + v = @view df[1:2, :] + + res = select(v, :a, :b, copycols=false) + + @test size(res) == (2, 2) + @test names(res) == ["a", "b"] + + @test res.a == v.a + @test res.b == v.b + + @test parent(res.a) === parent(v.a) + @test parent(res.b) === parent(v.b) +end \ No newline at end of file