Skip to content
27 changes: 16 additions & 11 deletions src/abstractdataframe/selection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
end
push!(seen_single_column, ind_idx)
end
push!(newinds, ind_idx)
end
return view(dfv, :, Cols(newinds...))
end
Expand Down
30 changes: 30 additions & 0 deletions test/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading