Skip to content

Commit

Permalink
Merge pull request #621 from catawbasam/master
Browse files Browse the repository at this point in the history
push!(df, row) for adding rows to a DataFrame
  • Loading branch information
johnmyleswhite committed Jun 10, 2014
2 parents 26ae562 + 2150279 commit 3cf97ff
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/DataFrames.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ export @~,
meltdf,
pivottable,
read_rda,
vecbind
vecbind,
push!

##############################################################################
##
Expand Down
76 changes: 76 additions & 0 deletions src/dataframe/dataframe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -999,3 +999,79 @@ function Base.convert(::Type{DataFrame}, A::Matrix)
end
nullable!(colnames::Array{Symbol,1},df::AbstractDataFrame)= (for i in colnames df[i]=DataArray(df[i]) end)
nullable!(colnums::Array{Int,1},df::AbstractDataFrame)= (for i in colnums df[i]=DataArray(df[i]) end)


##############################################################################
##
## push! a row onto a DataFrame
##
##############################################################################


function Base.push!(df::DataFrame, associative::Associative{Symbol,Any})
if length(associative) != length(df.columns)
msg = "Length of iterable does not match DataFrame column count."
throw(ArgumentError(msg))
end
i=1
for nm in names(df)
try
push!(df[nm], associative[nm])
catch
#clean up partial row
for j in 1:(i-1)
pop!(df[ names(df[j]) ])
end
msg = "Error adding value to column :$nm."
throw(ArgumentError(msg))
end
i=i+1
end
end


function Base.push!{K<:String}(df::DataFrame, associative::Associative{K,Any})
if length(associative) != length(df.columns)
msg = "Length of iterable does not match DataFrame column count."
throw(ArgumentError(msg))
end
i=1
for nm in names(df)
try
push!(df[nm], associative[string(nm)])
catch
#clean up partial row
colnames=[symbol(c) for c in names(df)]
for j in 1:(i-1)
pop!(df[colnames[j]])
end
msg = "Error adding value to column :$nm."
throw(ArgumentError(msg))
end
i=i+1
end
end


# array and tuple like collections
function Base.push!(df::DataFrame, iterable::Any)
if length(iterable) != length(df.columns)
msg = "Length of iterable does not match DataFrame column count."
throw(ArgumentError(msg))
end
i=1
for t in iterable
try
push!(df.columns[i], t)
catch
#clean up partial row
for j in 1:(i-1)
pop!(df.columns[j])
end
msg = "Error adding $t to column :$(names(df)[i]). Possible type mis-match."
throw(ArgumentError(msg))
end
i=i+1
end
end

33 changes: 33 additions & 0 deletions test/dataframe.jl
Original file line number Diff line number Diff line change
Expand Up @@ -134,4 +134,37 @@ module TestDataFrame

@test hash(convert(DataFrame, [1 2; 3 4])) == hash(convert(DataFrame, [1 2; 3 4]))
@test hash(convert(DataFrame, [1 2; 3 4])) != hash(convert(DataFrame, [1 3; 2 4]))


# push!(df, row)
df=DataFrame( first=[1,2,3], second=["apple","orange","pear"] )

dfb= DataFrame( first=[1,2], second=["apple","orange"] )
push!(dfb, {3,"pear"})
@test df==dfb

dfb= DataFrame( first=[1,2], second=["apple","orange"] )
push!(dfb, (3,"pear"))
@test df==dfb

dfb= DataFrame( first=[1,2], second=["apple","orange"] )
@test_throws ArgumentError push!(dfb, (33.33,"pear"))

dfb= DataFrame( first=[1,2], second=["apple","orange"] )
@test_throws ArgumentError push!(dfb, ("coconut",22))

dfb= DataFrame( first=[1,2], second=["apple","orange"] )
push!(dfb, [ :first=>3,:second=>"pear" ])
@test df==dfb

dfb= DataFrame( first=[1,2], second=["apple","orange"] )
push!(dfb, [ "first"=>3,"second"=>"pear" ])
@test df==dfb

dfb= DataFrame( first=[1,2], second=["apple","orange"] )
@test_throws ArgumentError push!(dfb, [ :first=>true,:second=>false ])

dfb= DataFrame( first=[1,2], second=["apple","orange"] )
@test_throws ArgumentError push!(dfb, ["first"=>"chicken", "second"=>"stuff" ])

end

0 comments on commit 3cf97ff

Please sign in to comment.