diff --git a/docs/src/man/basics.md b/docs/src/man/basics.md index ba56e0aab..c2e8790a1 100644 --- a/docs/src/man/basics.md +++ b/docs/src/man/basics.md @@ -81,7 +81,7 @@ Now let us initialize a `DataFrame` with several columns. This is a basic way to do it is the following: ```jldoctest dataframe -julia> DataFrame(A=1:3, B=5:7, fixed=1) +julia> DataFrame(A = 1:3, B = 5:7, fixed = 1) 3×3 DataFrame Row │ A B fixed │ Int64 Int64 Int64 @@ -158,7 +158,10 @@ It is also quite common to create a `DataFrame` from a `NamedTuple` of vectors or a vector of `NamedTuple`s. Here are some examples of these operations: ```jldoctest dataframe -julia> DataFrame((a=[1, 2], b=[3, 4])) +julia> namedtup = (a = [1, 2], b = [3, 4]) +(a = [1, 2], b = [3, 4]) + +julia> DataFrame(namedtup) 2×2 DataFrame Row │ a b │ Int64 Int64 @@ -166,7 +169,12 @@ julia> DataFrame((a=[1, 2], b=[3, 4])) 1 │ 1 3 2 │ 2 4 -julia> DataFrame([(a=1, b=0), (a=2, b=0)]) +julia> namedtup_vec = [(a = 1, b = 0), (a = 2, b = 0)] +2-element Vector{@NamedTuple{a::Int64, b::Int64}}: + (a = 1, b = 0) + (a = 2, b = 0) + +julia> DataFrame(namedtup_vec) 2×2 DataFrame Row │ a b │ Int64 Int64 @@ -178,7 +186,7 @@ julia> DataFrame([(a=1, b=0), (a=2, b=0)]) Sometimes your source data might have a heterogeneous set of columns for each observation. Here is an example: -``` +```jldoctest julia> source = [(type="circle", radius=10), (type="square", side=20)] 2-element Vector{NamedTuple{names, Tuple{String, Int64}} where names}: (type = "circle", radius = 10) @@ -189,7 +197,7 @@ If you want to create a data frame from such data containing all columns present one of the source observations, with a `missing` entry if some column is not present then you can use `Tables.dictcolumntable` function to help you create the desired data frame: -``` +```julia-repl julia> DataFrame(Tables.dictcolumntable(source)) 2×3 DataFrame Row │ type radius side @@ -204,7 +212,7 @@ about all columns present in the source data and properly instantiates them. If this function the `DataFrame` constructor would assume that the first row of data contains the set of columns present in the source, which would lead to an error in our example: -``` +```julia-repl julia> DataFrame(source) ERROR: type NamedTuple has no field radius ``` @@ -262,7 +270,7 @@ disk in the CSV format. First make sure you have CSV.jl installed. You can do it using the following instructions: -```julia +```julia-repl julia> using Pkg julia> Pkg.add("CSV") @@ -1024,7 +1032,7 @@ In order to compare the performance of indexing vs creation of a view let us run the following benchmark using the BenchmarkTools.jl package (please install it if you want to re-run this comparison): -```julia +```julia-repl julia> using BenchmarkTools julia> @btime $german[1:end-1, 1:end-1]; @@ -1459,17 +1467,17 @@ julia> insertcols!(df1, 1, :Country => "India") You can pass a column location where you want to put the inserted column as a second argument to the `insertcols!` function: -``` +```jldoctest dataframe julia> insertcols!(df1, 4, :b => exp(4)) 6×7 DataFrame - Row │ Country Age Sex b Job Customers City ⋯ - │ String String String Float64 Int64 String String ⋯ -─────┼────────────────────────────────────────────────────────────────────────── - 1 │ India Economics male 54.5982 4 Rohit Kanpur ⋯ + Row │ Country Age Sex b Job Customers City + │ String String String Float64 Int64 String String +─────┼───────────────────────────────────────────────────────────────────────── + 1 │ India Economics male 54.5982 4 Rohit Kanpur 2 │ India Economics female 54.5982 4 Akshat Lucknow 3 │ India Economics male 54.5982 4 Rahul Bhuvneshwar 4 │ India Economics transgender 54.5982 4 Aayush Jaipur - 5 │ India Economics female 54.5982 4 Prateek Ranchi ⋯ + 5 │ India Economics female 54.5982 4 Prateek Ranchi 6 │ India Economics female 54.5982 4 Anam Dehradoon ``` @@ -1517,28 +1525,28 @@ julia> german[:, Not(:Age)] Select columns starting from `:Sex` and ending at `:Housing`: -``` +```julia-repl julia> german[:, Between(:Sex, :Housing)] 1000×3 DataFrame - Row │ Sex Job Housing - │ String Int64 String -──────┼──────────────────────── - 1 │ male 2 own - 2 │ female 2 own - 3 │ male 1 own - 4 │ male 2 free - 5 │ male 2 free - 6 │ male 1 free - 7 │ male 2 own - 8 │ male 3 rent - ⋮ │ ⋮ ⋮ ⋮ - 994 │ male 3 own - 995 │ male 2 own - 996 │ female 1 own - 997 │ male 3 own - 998 │ male 2 own - 999 │ male 2 free - 1000 │ male 2 own + Row │ Sex Job Housing + │ String7 Int64 String7 +──────┼───────────────────────── + 1 │ male 2 own + 2 │ female 2 own + 3 │ male 1 own + 4 │ male 2 free + 5 │ male 2 free + 6 │ male 1 free + 7 │ male 2 own + 8 │ male 3 rent + ⋮ │ ⋮ ⋮ ⋮ + 994 │ male 3 own + 995 │ male 2 own + 996 │ female 1 own + 997 │ male 3 own + 998 │ male 2 own + 999 │ male 2 free + 1000 │ male 2 own 985 rows omitted ``` @@ -1686,7 +1694,7 @@ or column index which identifies a data frame column. `source_column_selector` may be used as the entire `operation` with `select` or `select!` to isolate or reorder columns. -```julia +```jldoctest dataframe julia> df = DataFrame(a = [1, 2, 3], b = [4, 5, 6], c = [7, 8, 9]) 3×3 DataFrame Row │ a b c @@ -1727,7 +1735,7 @@ julia> select(df, 2) `source_column_selector` may also be used as the entire `operation` with `subset` or `subset!` if the source column contains `Bool` values. -```julia +```jldoctest dataframe julia> df = DataFrame( name = ["Scott", "Jill", "Erica", "Jimmy"], minor = [false, true, false, true], @@ -1763,7 +1771,7 @@ See the [Indexing](@ref) API for the full list of possible values with reference `ERROR: syntax: whitespace not allowed after ":" used for quoting`, try using `All()`, `Cols(:)`, or `(:)` instead to select all columns. -```julia +```jldoctest dataframe julia> df = DataFrame( id = [1, 2, 3], first_name = ["José", "Emma", "Nathan"], @@ -1853,7 +1861,7 @@ When multiple columns are selected by `source_column_selector`, the `operation_function` will receive the columns as separate positional arguments in the order they were selected, e.g. `f(column1, column2, column3)`. -```julia +```jldoctest dataframe julia> df = DataFrame(a = [1, 2, 3], b = [4, 5, 4]) 3×2 DataFrame Row │ a b @@ -1900,7 +1908,7 @@ then you can wrap your element-wise function in `ByRow` like This will apply `my_elementwise_function` to every element in the column and then collect the results back into a vector. -```julia +```jldoctest dataframe julia> transform(df, [:a, :b] => ByRow(*)) 3×3 DataFrame Row │ a b a_b_* @@ -1936,7 +1944,7 @@ Alternatively, you may just want to define the function itself so it [broadcasts](https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting) over vectors. -```julia +```jldoctest dataframe julia> g(x) = x .+ 1 g (generic function with 1 method) @@ -1966,7 +1974,7 @@ julia> transform(df, [:a, :b] => h) are a convenient way to define and use an `operation_function` all within the manipulation function call. -```julia +```jldoctest dataframe julia> select(df, :a => ByRow(x -> x + 1)) 3×1 DataFrame Row │ a_function @@ -2024,7 +2032,7 @@ The distinction is somewhat similar to the difference between the built-in while `minimum` is defined to find the minimum value among the elements of a single collection argument. -```julia +```jldoctest dataframe julia> df = DataFrame(a = 1:2, b = 3:4, c = 5:6, d = 2:-1:1) 2×4 DataFrame Row │ a b c d @@ -2079,7 +2087,7 @@ julia> select(df, AsTable(Between(:b, :d)) => ByRow(mean)) # `mean` operates on `AsTable` can also be used to pass columns to a function which operates on fields of a `NamedTuple`. -```julia +```jldoctest dataframe julia> df = DataFrame(a = 1:2, b = 3:4, c = 5:6, d = 7:8) 2×4 DataFrame Row │ a b c d @@ -2114,7 +2122,7 @@ from its default value (`true`) to `renamecols=false`. This option prevents the function name from being appended to the column name as it usually would be. -```julia +```jldoctest dataframe julia> df = DataFrame(a=1:4, b=5:8) 4×2 DataFrame Row │ a b @@ -2145,7 +2153,7 @@ specify your own `new_column_names`. the name of the new column(s). `new_column_names` may be a symbol, string, function, vector of symbols, vector of strings, or `AsTable`. -```julia +```jldoctest dataframe julia> df = DataFrame(a=1:4, b=5:8) 4×2 DataFrame Row │ a b @@ -2193,7 +2201,7 @@ However, there are `rename` and `rename!` functions, which accept similar syntax, that tend to be more useful for this operation. -```julia +```jldoctest dataframe julia> df = DataFrame(a=1:4, b=5:8) 4×2 DataFrame Row │ a b @@ -2241,7 +2249,7 @@ rather than being added to the end. This can be done by manually specifying an existing column name or by using the `renamecols=false` keyword argument. -```julia +```jldoctest dataframe julia> df = DataFrame(a=1:4, b=5:8) 4×2 DataFrame Row │ a b @@ -2286,7 +2294,7 @@ julia> transform(df, :b => (x -> x .+ 10) => :a) # replace column :a Actually, `renamecols=false` just prevents the function name from being appended to the final column name such that the operation is *usually* returned to the same column. -```julia +```jldoctest dataframe julia> transform(df, [:a, :b] => +) # new column name is all source columns and function name 4×3 DataFrame Row │ a b a_b_+ @@ -2322,7 +2330,7 @@ In the `source_column_selector => operation_function => new_column_names` operat `new_column_names` may also be a renaming function which operates on a string to create the destination column names programmatically. -```julia +```jldoctest dataframe julia> df = DataFrame(a=1:4, b=5:8) 4×2 DataFrame Row │ a b @@ -2362,7 +2370,7 @@ julia> transform(df, :a => (x -> 10 .* x) => (s -> "new_" * s)) # with anonymous It is a good idea to wrap anonymous functions in parentheses to avoid the `=>` operator accidently becoming part of the anonymous function. The examples above do not work correctly without the parentheses! - ```julia + ```julia-repl julia> transform(df, :a => x -> 10 .* x => add_prefix) # Not what we wanted! 4×3 DataFrame Row │ a b a_function @@ -2391,7 +2399,7 @@ To work around this limitation, use the `source_column_selector => operation_function => new_column_names` operation form with `identity` as the `operation_function`. -```julia +```jldoctest dataframe julia> transform(df, :a => add_prefix) ERROR: MethodError: no method matching *(::String, ::Vector{Int64}) @@ -2410,7 +2418,7 @@ In this case though, it is probably again more useful to use the `rename` or `rename!` function rather than one of the manipulation functions in order to rename in-place and avoid the intermediate `operation_function`. -```julia +```jldoctest dataframe julia> rename(add_prefix, df) # rename all columns with a function 4×2 DataFrame Row │ new_a new_b @@ -2439,7 +2447,7 @@ It is possible to split the data contained inside a single column into multiple new columns by supplying a vector of strings or symbols as `new_column_names`. -```julia +```jldoctest dataframe julia> df = DataFrame(data = [(1,2), (3,4)]) # vector of tuples 2×1 DataFrame Row │ data @@ -2459,7 +2467,7 @@ julia> transform(df, :data => [:first, :second]) # manual naming This kind of data splitting can even be done automatically with `AsTable`. -```julia +```jldoctest dataframe julia> transform(df, :data => AsTable) # default automatic naming with tuples 2×3 DataFrame Row │ data x1 x2 @@ -2471,7 +2479,7 @@ julia> transform(df, :data => AsTable) # default automatic naming with tuples If a data frame column contains `NamedTuple`s, then `AsTable` will preserve the field names. -```julia +```jldoctest dataframe julia> df = DataFrame(data = [(a=1,b=2), (a=3,b=4)]) # vector of named tuples 2×1 DataFrame Row │ data @@ -2499,7 +2507,7 @@ julia> transform(df, :data => AsTable) # keeps names from named tuples Renaming functions also work for multi-column transformations, but they must operate on a vector of strings. -```julia +```jldoctest dataframe julia> df = DataFrame(data = [(1,2), (3,4)]) 2×1 DataFrame Row │ data @@ -2531,7 +2539,7 @@ Passing multiple operations is especially useful for the `select`, `select!`, and `combine` manipulation functions, since they only retain columns which are a result of the passed operations. -```julia +```jldoctest dataframe julia> df = DataFrame(a = 1:4, b = [50,50,60,60], c = ["hat","bat","cat","dog"]) 4×3 DataFrame Row │ a b c @@ -2559,7 +2567,7 @@ julia> select(df, :c, :b, :a) # re-order columns 3 │ cat 60 3 4 │ dog 60 4 -ulia> select(df, :b, :) # `:` here means all other columns +julia> select(df, :b, :) # `:` here means all other columns 4×3 DataFrame Row │ b a c │ Int64 Int64 String @@ -2607,7 +2615,7 @@ This is a good way to make manipulations with many operations more readable. Passing multiple operations to `subset` or `subset!` is an easy way to narrow in on a particular row of data. -```julia +```jldoctest dataframe julia> subset( df, :b => ByRow(==(60)), @@ -2625,13 +2633,13 @@ as it existed before the function call i.e. you cannot use newly created columns for subsequent operations within the same manipulation. -```julia +```jldoctest dataframe julia> transform( df, [:a, :b] => ByRow(+) => :d, :d => (x -> x ./ 2), ) # requires two separate transformations -ERROR: ArgumentError: column name :d not found in the data frame; existing most similar names are: :a, :b and :c +ERROR: ArgumentError: column name "d" not found in the data frame; existing most similar names are: "a", "b" and "c" julia> new_df = transform(df, [:a, :b] => ByRow(+) => :d) 4×4 DataFrame @@ -2674,7 +2682,7 @@ In DataFrames.jl, a symbol, string, or integer may be used to select a single column. Some `Pair`s with these types are below. -```julia +```jldoctest dataframe julia> typeof(:x => :a) Pair{Symbol, Symbol} @@ -2688,7 +2696,7 @@ Pair{Int64, String} Any of the `Pair`s above could be used to rename the first column of the data frame below to `a`. -```julia +```jldoctest dataframe julia> df = DataFrame(x = 1:3, y = 4:6) 3×2 DataFrame Row │ x y @@ -2721,7 +2729,7 @@ What should we do if we want to keep and rename both the `x` and `y` column? One option is to supply a `Vector` of operation `Pair`s to `select`. `select` will process all of these operations in order. -```julia +```jldoctest dataframe julia> ["x" => "a", "y" => "b"] 2-element Vector{Pair{String, String}}: "x" => "a" @@ -2739,7 +2747,7 @@ julia> select(df, ["x" => "a", "y" => "b"]) We can use broadcasting to simplify the syntax above. -```julia +```jldoctest dataframe julia> ["x", "y"] .=> ["a", "b"] 2-element Vector{Pair{String, String}}: "x" => "a" @@ -2760,7 +2768,7 @@ argument whether the individual pairs are written out explicitly or constructed with broadcasting. The broadcasting is applied before the call to `select`. -```julia +```jldoctest dataframe julia> ["x" => "a", "y" => "b"] == (["x", "y"] .=> ["a", "b"]) true ``` @@ -2782,7 +2790,7 @@ true In Julia, a non-vector broadcasted with a vector will be repeated in each resultant pair element. -```julia +```jldoctest dataframe julia> ["x", "y"] .=> :a # :a is repeated 2-element Vector{Pair{String, Symbol}}: "x" => :a @@ -2796,7 +2804,7 @@ julia> 1 .=> [:a, :b] # 1 is repeated We can use this fact to easily broadcast an `operation_function` to multiple columns. -```julia +```jldoctest dataframe julia> f(x) = 2 * x f (generic function with 1 method) @@ -2832,7 +2840,7 @@ julia> select(df, ["x", "y"] .=> f .=> ["a", "b"]) # apply f with manual column A renaming function can be applied to multiple columns in the same way. It will also be repeated in each operation `Pair`. -```julia +```jldoctest dataframe julia> newname(s::String) = s * "_new" newname (generic function with 1 method) @@ -2858,7 +2866,7 @@ Thus, `:x => :y => :z` becomes a nested `Pair`, where `:x` is the first element and points to the `Pair` `:y => :z`, which is the second element. -```julia +```jldoctest dataframe julia> p = :x => :y => :z :x => (:y => :z) @@ -2884,7 +2892,7 @@ often similarities in the column names or position can be exploited to avoid tedious selection. Consider a data frame with temperature data at three different locations taken over time. -```julia +```jldoctest dataframe julia> df = DataFrame(Time = 1:4, Temperature1 = [20, 23, 25, 28], Temperature2 = [33, 37, 41, 44], @@ -2903,7 +2911,7 @@ To convert all of the temperature data in one transformation, we just need to define a conversion function and broadcast it to all of the "Temperature" columns. -```julia +```jldoctest dataframe julia> celsius_to_kelvin(x) = x + 273 celsius_to_kelvin (generic function with 1 method) @@ -2923,7 +2931,7 @@ julia> transform( ``` Or, simultaneously changing the column names: -```julia +```jldoctest dataframe julia> rename_function(s) = "Temperature $(last(s)) (K)" rename_function (generic function with 1 method) @@ -2960,7 +2968,7 @@ julia> select( You could also broadcast different columns to different functions by supplying a vector of functions. -```julia +```jldoctest dataframe julia> df = DataFrame(a=1:4, b=5:8) 4×2 DataFrame Row │ a b @@ -2991,7 +2999,7 @@ julia> transform(df, [:a, :b] .=> [f1, f2]) However, this form is not much more convenient than supplying multiple individual operations. -```julia +```jldoctest dataframe julia> transform(df, [:a => f1, :b => f2]) # same manipulation as previous 4×4 DataFrame Row │ a b a_f1 b_f2 @@ -3009,7 +3017,7 @@ by changing the vector of functions to a 1-by-x matrix of functions. (Recall that a list, a vector, or a matrix of operation pairs are all valid for passing to the manipulation functions.) -```julia +```jldoctest dataframe julia> [:a, :b] .=> [f1 f2] # No comma `,` between f1 and f2 2×2 Matrix{Pair{Symbol}}: :a=>f1 :a=>f2 @@ -3062,7 +3070,7 @@ and place the result in a new third column. **Setup:** -```julia +```jldoctest dataframe julia> df = DataFrame(x = 1:3, y = 4:6) # define a data frame 3×2 DataFrame Row │ x y @@ -3075,7 +3083,7 @@ julia> df = DataFrame(x = 1:3, y = 4:6) # define a data frame **Manipulation:** -```julia +```jldoctest dataframe julia> transform!(df, [:x, :y] => (+) => :z) 3×3 DataFrame Row │ x y z @@ -3088,7 +3096,7 @@ julia> transform!(df, [:x, :y] => (+) => :z) **Dot Syntax:** -```julia +```jldoctest dataframe julia> df.z = df.x + df.y 3-element Vector{Int64}: 5 @@ -3117,7 +3125,7 @@ and then `df` would not have been altered. The approach with dot syntax is very versatile since the data getting, mathematics, and data setting can be separate steps. -```julia +```jldoctest dataframe julia> df.x # dot syntax returns a vector 3-element Vector{Int64}: 1 @@ -3148,7 +3156,7 @@ stored in variables. Imagine this setup data was read from a file and/or entered by a user at runtime. -```julia +```jldoctest dataframe julia> df = DataFrame("My First Column" => 1:3, "My Second Column" => 4:6) # define a data frame 3×2 DataFrame Row │ My First Column My Second Column @@ -3163,14 +3171,14 @@ julia> c1 = "My First Column"; c2 = "My Second Column"; c3 = "My Third Column"; **Dot Syntax:** -```julia +```jldoctest dataframe julia> df.c1 # dot syntax expects an explicit column name and cannot be used to access variable column name ERROR: ArgumentError: column name :c1 not found in the data frame ``` **Indexing:** -```julia +```jldoctest dataframe julia> df[:, c3] = df[:, c1] + df[:, c2] # access columns with names stored in variables 3-element Vector{Int64}: 5 @@ -3189,7 +3197,7 @@ julia> df # see that the previous expression updated the data frame `df` **Manipulation:** -```julia +```jldoctest dataframe julia> transform!(df, [c1, c2] => (+) => c3) # access columns with names stored in variables 3×3 DataFrame Row │ My First Column My Second Column My Third Column @@ -3206,7 +3214,7 @@ This can be helpful when dealing with long variable and column names. **Setup:** -```julia +```jldoctest dataframe julia> my_very_long_data_frame_name = DataFrame( "My First Column" => 1:3, "My Second Column" => 4:6 @@ -3223,8 +3231,7 @@ julia> c1 = "My First Column"; c2 = "My Second Column"; c3 = "My Third Column"; ``` **Manipulation:** -```julia - +```jldoctest dataframe julia> transform!(my_very_long_data_frame_name, [c1, c2] => (+) => c3) 3×3 DataFrame Row │ My First Column My Second Column My Third Column @@ -3237,7 +3244,7 @@ julia> transform!(my_very_long_data_frame_name, [c1, c2] => (+) => c3) **Indexing:** -```julia +```jldoctest dataframe julia> my_very_long_data_frame_name[:, c3] = my_very_long_data_frame_name[:, c1] + my_very_long_data_frame_name[:, c2] 3-element Vector{Int64}: 5 @@ -3259,7 +3266,7 @@ it is easier to operate on a subset of columns. **Setup:** -```julia +```jldoctest dataframe julia> df = DataFrame(x = 1:3, y = 4:6, z = 7:9) # define data frame 3×3 DataFrame Row │ x y z @@ -3272,14 +3279,14 @@ julia> df = DataFrame(x = 1:3, y = 4:6, z = 7:9) # define data frame **Dot Syntax:** -```julia +```jldoctest dataframe julia> df.Not(:x) # will not work; requires a literal column name ERROR: ArgumentError: column name :Not not found in the data frame ``` **Manipulation:** -```julia +```jldoctest dataframe julia> transform!(df, Not(:x) => ByRow(max)) # find maximum value across all rows except for column `x` 3×4 DataFrame Row │ x y z y_z_max @@ -3292,7 +3299,7 @@ julia> transform!(df, Not(:x) => ByRow(max)) # find maximum value across all ro **Indexing:** -```julia +```jldoctest dataframe julia> df[:, :y_z_max] = maximum.(eachrow(df[:, Not(:x)])) # find maximum value across all rows except for column `x` 3-element Vector{Int64}: 7 @@ -3313,7 +3320,7 @@ Moreover, indexing can operate on a subset of columns *and* rows. **Indexing:** -```julia +```jldoctest dataframe julia> y_z_max_row3 = maximum(df[3, Not(:x)]) # find maximum value across row 3 except for column `x` 9 ``` diff --git a/docs/src/man/comparisons.md b/docs/src/man/comparisons.md index f499abade..2ba2e7f7e 100644 --- a/docs/src/man/comparisons.md +++ b/docs/src/man/comparisons.md @@ -146,7 +146,7 @@ Name: x, dtype: int64 For DataFrames.jl, it looks like this: -```julia +```julia-repl julia> combine(groupby(df, :grp), :x => mean) 2×2 DataFrame Row │ grp x_mean diff --git a/docs/src/man/customizing_output.md b/docs/src/man/customizing_output.md index d6b6c749e..bf1e764b8 100644 --- a/docs/src/man/customizing_output.md +++ b/docs/src/man/customizing_output.md @@ -40,9 +40,7 @@ julia> df = DataFrame( c = ["short", "a very very very very very long string", "ok"] ); -julia> # This is the default output. - -julia> df +julia> df # This is the default output. 3×3 DataFrame Row │ a b c │ Int64 Float64 String @@ -62,9 +60,7 @@ julia> show(df; truncate = 0) 2 │ 2 -1.2 a very very very very very long string 3 │ 3 42.0 ok -julia> # Hide row numbers. - -julia> show(df; show_row_number = false) +julia> show(df; show_row_number = false) # Hide row numbers. 3×3 DataFrame a b c Int64 Float64 String @@ -73,9 +69,7 @@ julia> show(df; show_row_number = false) 2 -1.2 a very very very very very long … 3 42.0 ok -julia> # Hide the column element types in text output. - -julia> show(df; eltypes = false) +julia> show(df; eltypes = false) # Hide the column element types in text output. 3×3 DataFrame Row │ a b c ─────┼───────────────────────────────────────────── @@ -119,9 +113,7 @@ julia> df = DataFrame( E = [ 0.26, -1.67, 2.22, -0.75, 1.05, -0.48, -2.93] ); -julia> # This is the default output. - -julia> df +julia> df # This is the default output. 7×5 DataFrame Row │ A B C D E │ Float64 Float64 Float64 Float64 Float64 @@ -157,15 +149,10 @@ julia> show(df; formatters = [parentheses_fmt]) The color of the cells can be changed using highlighters. The following example shows how to highlight negative values in red in HTML output (e.g. in Jupyter). -```julia +```julia-repl julia> hl = HtmlHighlighter((data, i, j) -> data[i, j] < 0, ["color" => "red"]); -julia> show( - stdout, - MIME("text/html"), - df; - highlighters = [hl] - ) +julia> show(stdout, MIME("text/html"), df; highlighters = [hl]) ``` You can also add summary rows at the bottom of a table using PrettyTables.jl keywords. Pass @@ -211,4 +198,4 @@ julia> show( ``` For more customization options, check the -[PrettyTables.jl documentation](https://ronisbr.github.io/PrettyTables.jl/stable/). \ No newline at end of file +[PrettyTables.jl documentation](https://ronisbr.github.io/PrettyTables.jl/stable/). diff --git a/docs/src/man/joins.md b/docs/src/man/joins.md index c0f32bfd2..0916b057e 100644 --- a/docs/src/man/joins.md +++ b/docs/src/man/joins.md @@ -481,7 +481,7 @@ Note that in this case the order and number of rows in the left table is not changed. Therefore, in particular, it is not allowed to have duplicate keys in the right table: -``` +```julia-repl julia> leftjoin!(main, DataFrame(id=[2, 2], info_bad=["a", "b"]), on=:id) ERROR: ArgumentError: duplicate rows found in right table ``` diff --git a/docs/src/man/split_apply_combine.md b/docs/src/man/split_apply_combine.md index dad16408c..f9928e86e 100644 --- a/docs/src/man/split_apply_combine.md +++ b/docs/src/man/split_apply_combine.md @@ -323,7 +323,7 @@ julia> combine(iris_gdf, :PetalLength => (x -> [extrema(x)]) => [:min, :max]) ``` To get row number for each observation within each group use the `eachindex` function: -``` +```jldoctest sac julia> combine(iris_gdf, eachindex) 150×2 DataFrame Row │ Species eachindex @@ -332,11 +332,20 @@ julia> combine(iris_gdf, eachindex) 1 │ Iris-setosa 1 2 │ Iris-setosa 2 3 │ Iris-setosa 3 + 4 │ Iris-setosa 4 + 5 │ Iris-setosa 5 + 6 │ Iris-setosa 6 + 7 │ Iris-setosa 7 + 8 │ Iris-setosa 8 ⋮ │ ⋮ ⋮ + 144 │ Iris-virginica 44 + 145 │ Iris-virginica 45 + 146 │ Iris-virginica 46 + 147 │ Iris-virginica 47 148 │ Iris-virginica 48 149 │ Iris-virginica 49 150 │ Iris-virginica 50 - 144 rows omitted + 135 rows omitted ``` Contrary to `combine`, the `select` and `transform` functions always return @@ -344,36 +353,53 @@ a data frame with the same number and order of rows as the source. In the example below the return values in columns `:SepalLength_SepalWidth_cor` and `:nrow` are broadcasted to match the number of elements in each group: -``` + +```jldoctest sac julia> select(iris_gdf, 1:2 => cor) 150×2 DataFrame Row │ Species SepalLength_SepalWidth_cor - │ String Float64 + │ String15 Float64 ─────┼──────────────────────────────────────────── 1 │ Iris-setosa 0.74678 2 │ Iris-setosa 0.74678 3 │ Iris-setosa 0.74678 4 │ Iris-setosa 0.74678 + 5 │ Iris-setosa 0.74678 + 6 │ Iris-setosa 0.74678 + 7 │ Iris-setosa 0.74678 + 8 │ Iris-setosa 0.74678 ⋮ │ ⋮ ⋮ + 144 │ Iris-virginica 0.457228 + 145 │ Iris-virginica 0.457228 + 146 │ Iris-virginica 0.457228 + 147 │ Iris-virginica 0.457228 148 │ Iris-virginica 0.457228 149 │ Iris-virginica 0.457228 150 │ Iris-virginica 0.457228 - 143 rows omitted + 135 rows omitted julia> transform(iris_gdf, :Species => x -> chop.(x, head=5, tail=0)) 150×6 DataFrame - Row │ SepalLength SepalWidth PetalLength PetalWidth Species Species_function - │ Float64 Float64 Float64 Float64 String SubString… -─────┼──────────────────────────────────────────────────────────────────────────────────── - 1 │ 5.1 3.5 1.4 0.2 Iris-setosa setosa - 2 │ 4.9 3.0 1.4 0.2 Iris-setosa setosa - 3 │ 4.7 3.2 1.3 0.2 Iris-setosa setosa - 4 │ 4.6 3.1 1.5 0.2 Iris-setosa setosa - ⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ - 148 │ 6.5 3.0 5.2 2.0 Iris-virginica virginica - 149 │ 6.2 3.4 5.4 2.3 Iris-virginica virginica - 150 │ 5.9 3.0 5.1 1.8 Iris-virginica virginica - 143 rows omitted + Row │ SepalLength SepalWidth PetalLength PetalWidth Species Speci ⋯ + │ Float64 Float64 Float64 Float64 String15 Strin ⋯ +─────┼────────────────────────────────────────────────────────────────────────── + 1 │ 5.1 3.5 1.4 0.2 Iris-setosa setos ⋯ + 2 │ 4.9 3.0 1.4 0.2 Iris-setosa setos + 3 │ 4.7 3.2 1.3 0.2 Iris-setosa setos + 4 │ 4.6 3.1 1.5 0.2 Iris-setosa setos + 5 │ 5.0 3.6 1.4 0.2 Iris-setosa setos ⋯ + 6 │ 5.4 3.9 1.7 0.4 Iris-setosa setos + 7 │ 4.6 3.4 1.4 0.3 Iris-setosa setos + 8 │ 5.0 3.4 1.5 0.2 Iris-setosa setos + ⋮ │ ⋮ ⋮ ⋮ ⋮ ⋮ ⋱ + 144 │ 6.8 3.2 5.9 2.3 Iris-virginica virgi ⋯ + 145 │ 6.7 3.3 5.7 2.5 Iris-virginica virgi + 146 │ 6.7 3.0 5.2 2.3 Iris-virginica virgi + 147 │ 6.3 2.5 5.0 1.9 Iris-virginica virgi + 148 │ 6.5 3.0 5.2 2.0 Iris-virginica virgi ⋯ + 149 │ 6.2 3.4 5.4 2.3 Iris-virginica virgi + 150 │ 5.9 3.0 5.1 1.8 Iris-virginica virgi + 1 column and 135 rows omitted ``` All functions also support the `do` block form. However, as noted above, @@ -730,7 +756,7 @@ syntax in `combine`, `select` or `transform` will usually be faster for large `GroupedDataFrame` objects than iterating them, with the difference that they produce a data frame. An operation corresponding to the example above is: -``` +```julia-repl julia> combine(iris_gdf, nrow) 3×2 DataFrame Row │ Species nrow @@ -1311,7 +1337,7 @@ julia> keys(groupby(df, :volume)) If you want to have them sorted in ascending order pass `sort=true`: -``` +```julia-repl julia> keys(groupby(df, :volume, sort=true)) 7-element DataFrames.GroupKeys{GroupedDataFrame{DataFrame}}: GroupKey: (volume = 1,) @@ -1328,7 +1354,7 @@ by or pass a named tuple as `sort` keyword argument containing one or more of `alg`, `lt`, `by`, `rev`, and `order` fields that will be treated just like in [`sortperm`](@ref): -``` +```julia-repl julia> keys(groupby(df, [:customer_id, order(:volume, rev=true)])) 6-element DataFrames.GroupKeys{GroupedDataFrame{DataFrame}}: GroupKey: (customer_id = "a", volume = 2) diff --git a/docs/src/man/working_with_dataframes.md b/docs/src/man/working_with_dataframes.md index a74298c18..458dd27e7 100644 --- a/docs/src/man/working_with_dataframes.md +++ b/docs/src/man/working_with_dataframes.md @@ -603,7 +603,7 @@ julia> df[:, :x1] By default `select` copies columns of a passed source data frame. In order to avoid copying, pass `copycols=false`: -``` +```jldoctest dataframe julia> df2 = select(df, :x1) 2×1 DataFrame Row │ x1 @@ -668,7 +668,7 @@ julia> transform(df, All() => +) Using the `ByRow` wrapper, we can easily compute for each row the name of column with the highest score: -``` +```julia-repl julia> using Random julia> Random.seed!(1); @@ -709,8 +709,8 @@ julia> transform(df, AsTable(:) => ByRow(argmax) => :prediction) In the most complex example below we compute row-wise sum, number of elements, and mean, while ignoring missing values. -``` -julia> using Statistics +```jldoctest +julia> using DataFrames, Statistics julia> df = DataFrame(x=[1, 2, missing], y=[1, missing, missing]) 3×2 DataFrame @@ -844,7 +844,7 @@ want to focus on the most common usage patterns. A `DataFrame` can store values of any type as its columns, for example below we show how one can store a `Tuple`: -``` +```jldoctest dataframe julia> df2 = combine(df, All() .=> extrema) 1×2 DataFrame Row │ A_extrema B_extrema @@ -858,7 +858,7 @@ minima and maxima. This can be achieved by passing multiple columns for the outp Here is an example of how this can be done by writing the column names by-hand for a single input column: -``` +```jldoctest dataframe julia> combine(df2, "A_extrema" => identity => ["A_min", "A_max"]) 1×2 DataFrame Row │ A_min A_max @@ -869,7 +869,7 @@ julia> combine(df2, "A_extrema" => identity => ["A_min", "A_max"]) You can extend it to handling all columns in `df2` using broadcasting: -``` +```jldoctest dataframe julia> combine(df2, All() .=> identity .=> [["A_min", "A_max"], ["B_min", "B_max"]]) 1×4 DataFrame Row │ A_min A_max B_min B_max @@ -882,7 +882,7 @@ This approach works, but can be improved. Instead of writing all the column name manually we can instead use a function as a way to specify target column names based on source column names: -``` +```jldoctest dataframe julia> combine(df2, All() .=> identity .=> c -> first(c) .* ["_min", "_max"]) 1×4 DataFrame Row │ A_min A_max B_min B_max @@ -898,7 +898,7 @@ treated as a transformation and not as a rule for target column names generation You might want to perform the transformation of the source data frame into the result we have just shown in one step. This can be achieved with the following expression: -``` +```jldoctest dataframe julia> combine(df, All() .=> Ref∘extrema .=> c -> c .* ["_min", "_max"]) 1×4 DataFrame Row │ A_min A_max B_min B_max @@ -912,10 +912,9 @@ Without `Ref`, `combine` iterates the contents of the value returned by the oper which in our case is a tuple of numbers, and tries to expand it assuming that each produced value represents one row, so one gets an error: -``` +```jldoctest dataframe julia> combine(df, All() .=> extrema .=> [c -> c .* ["_min", "_max"]]) -ERROR: ArgumentError: 'Tuple{Int64, Int64}' iterates 'Int64' values, -which doesn't satisfy the Tables.jl `AbstractRow` interface +ERROR: ArgumentError: 'Tuple{Int64, Int64}' iterates 'Int64' values, which doesn't satisfy the Tables.jl `AbstractRow` interface ``` Note that we used `Ref` as it is a container that is typically used in DataFrames.jl when one diff --git a/src/abstractdataframe/io.jl b/src/abstractdataframe/io.jl index 2be7497ce..e3d177187 100644 --- a/src/abstractdataframe/io.jl +++ b/src/abstractdataframe/io.jl @@ -23,9 +23,9 @@ implicit row ID column contained in every `AbstractDataFrame`. # Arguments - `df::AbstractDataFrame`: The data frame whose columns will be printed. - `io::IO`: The `IO` to which `df` is to be printed -- `rowindices1::AbstractVector{Int}: A set of indices of the first +- `rowindices1::AbstractVector{Int}`: A set of indices of the first chunk of the AbstractDataFrame that would be rendered to IO. -- `rowindices2::AbstractVector{Int}: A set of indices of the second +- `rowindices2::AbstractVector{Int}`: A set of indices of the second chunk of the AbstractDataFrame that would be rendered to IO. Can be empty if the AbstractDataFrame would be printed without any ellipses. diff --git a/src/abstractdataframe/selectionfast.jl b/src/abstractdataframe/selectionfast.jl index 40a8bea16..c68d94a0d 100644 --- a/src/abstractdataframe/selectionfast.jl +++ b/src/abstractdataframe/selectionfast.jl @@ -43,7 +43,7 @@ scenarios even standard aggregation functions should not be considered to provide reliable output, and users are recommended to switch to higher precision calculations. An example of a case when standard `sum` is affected by the situation discussed is: -``` +```julia-repl julia> sum(Any[typemax(Int), typemax(Int), 1.0]) -1.0 diff --git a/src/other/metadata.jl b/src/other/metadata.jl index 60a283d5a..c1f3f41c8 100644 --- a/src/other/metadata.jl +++ b/src/other/metadata.jl @@ -97,7 +97,6 @@ See also: [`metadatakeys`](@ref), [`metadata!`](@ref), [`deletecolmetadata!`](@ref), [`emptycolmetadata!`](@ref). $TABLEMETA_EXAMPLE -``` """ function metadata(df::DataFrame, key::AbstractString, default=MetadataMissingDefault(); style::Bool=false) @@ -186,7 +185,6 @@ See also: [`metadata`](@ref), [`metadatakeys`](@ref), [`deletecolmetadata!`](@ref), [`emptycolmetadata!`](@ref). $TABLEMETA_EXAMPLE -``` """ function metadata!(df::DataFrame, key::AbstractString, value::Any; style::Symbol=:default) @@ -245,7 +243,6 @@ See also: [`metadata`](@ref), [`metadatakeys`](@ref), [`deletecolmetadata!`](@ref), [`emptycolmetadata!`](@ref). $TABLEMETA_EXAMPLE -``` """ function deletemetadata!(df::DataFrame, key::AbstractString) meta = getfield(df, :metadata) @@ -355,7 +352,6 @@ See also: [`metadata`](@ref), [`metadatakeys`](@ref), [`deletecolmetadata!`](@ref), [`emptycolmetadata!`](@ref). $COLMETADATA_EXAMPLE -``` """ function colmetadata(df::DataFrame, col::ColumnIndex, key::AbstractString, default=MetadataMissingDefault(); style::Bool=false) @@ -421,7 +417,6 @@ See also: [`metadata`](@ref), [`metadatakeys`](@ref), [`deletecolmetadata!`](@ref), [`emptycolmetadata!`](@ref). $COLMETADATA_EXAMPLE -``` """ function colmetadatakeys(df::DataFrame, col::ColumnIndex) idx = index(df)[col] # check if column exists and get its integer index @@ -483,7 +478,6 @@ See also: [`metadata`](@ref), [`metadatakeys`](@ref), [`deletecolmetadata!`](@ref), [`emptycolmetadata!`](@ref). $COLMETADATA_EXAMPLE -``` """ function colmetadata!(df::DataFrame, col::ColumnIndex, key::AbstractString, value::Any; style::Symbol=:default)