# Complex DataFrames.jl transform by row

**URL:** https://discourse.julialang.org/t/complex-dataframes-jl-transform-by-row/112781
**Category:** Data
**Tags:** question, dataframes
**Created:** [April 10, 2024, 2:54pm UTC](https://discourse.julialang.org/t/complex-dataframes-jl-transform-by-row/112781 "2024-04-10T14:54:28Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![chelseas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chelseas/32/12148_2.png) [@chelseas](https://discourse.julialang.org/u/chelseas)
#### Post date: [April 10, 2024, 2:54pm UTC](https://discourse.julialang.org/t/complex-dataframes-jl-transform-by-row/112781/1 "2024-04-10T14:54:28Z")

</div>

I’m a bit rusty on data table programming and I am getting stuck using the DataFrames.jl package when trying to applying a complex function to every row of a DataFrame. e.g., I would like to take the entirety of a `row`, and use a bunch of different columns (imagine, all of them) in a complex calculation to calculate a new column.  
I have tried:  
`transform!(groupby(data, :uniqueID), complex_calc)` and i think it does what i want, adding a new column called `x1` but if i try to pass a name using:  
`transform!(groupby(data, :uniqueID), complex_calc => "newname")` it gives the error:

```julia
ArgumentError: invalid index: var"#complex_calc#254"{String}("wrapped_function_arg") => "newname" of type Pair{var"#complex_calc#254"{String}, String}

```

I have also tried:  
`transform(data, :, :, complex_calc)` which gives incorrect results

---

<div class="post-metadata">

### Author: ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)
#### Post date: [April 10, 2024, 3:04pm UTC](https://discourse.julialang.org/t/complex-dataframes-jl-transform-by-row/112781/2 "2024-04-10T15:04:42Z")

</div>

Probably you want:

```julia
transform(groupby(data, :uniqueID), AsTable(All()) => complex_calc => "newname")

```

if you want to work with all the columns.

However, note that in this case you can also just do:

```julia
[complex_calc(x) fo x in groupby(data, :uniqueID)]

```

(in which case the result will be a vector not a data frame, but sometimes you might prefer that.

---

<div class="post-metadata">

### Author: ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)
#### Post date: [April 10, 2024, 3:25pm UTC](https://discourse.julialang.org/t/complex-dataframes-jl-transform-by-row/112781/3 "2024-04-10T15:25:51Z")

</div>

There are a number of ways to do this depending on how you have constructed `complex_calc`.

Some comments:

1. I think the grouping isn’t doing anything for you if each group is a single row.
2. The first element in the Pair should be the columns to pass to `complex_calc`. Then the second element is `complex_calc`, and the third is the new column name.
3. Remember that columns are passed as vectors to `complex_calc`. If you instead want the elements of the row passed as scalar arguments, then you need to wrap `complex_calc` in `ByRow` inside the transform.
4. `AsTable` can be used to pass an entire row as one argument, but the columns of the table are still vectors unless you use `ByRow` too.

```julia
using DataFrames

complex_calc1(x, y, z) = x * y + z
complex_calc2(row) = row.x * row.y + row.z

df = DataFrame(id = "Row " .* string.(1:3), x = 1:3, y = 4:6, z = 7:9)

transform!(df, Not(:id) => ByRow(complex_calc1) => "Positional Argument Method")
transform!(df, AsTable(:) => ByRow(complex_calc2) => "Row Method")
df."Direct Argument Method" = complex_calc1.(df.x, df.y, df.z)
df."Direct Row Method" = complex_calc2.(eachrow(df))

```

---

<div class="post-metadata">

### Author: ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)
#### Post date: [April 10, 2024, 3:47pm UTC](https://discourse.julialang.org/t/complex-dataframes-jl-transform-by-row/112781/4 "2024-04-10T15:47:53Z")

</div>

A side-note is that the first three are going to be very fast. The last one will be slow.

---

<div class="post-metadata">

### Author: ![chelseas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chelseas/32/12148_2.png) [@chelseas](https://discourse.julialang.org/u/chelseas)
#### Post date: [April 23, 2024, 2:59pm UTC](https://discourse.julialang.org/t/complex-dataframes-jl-transform-by-row/112781/5 "2024-04-23T14:59:39Z")

</div>

I got “unknown algorithm” errors when trying to use the 2nd and 4th methods. 😕 Any idea why?

---

<div class="post-metadata">

### Author: ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)
#### Post date: [April 23, 2024, 4:19pm UTC](https://discourse.julialang.org/t/complex-dataframes-jl-transform-by-row/112781/6 "2024-04-23T16:19:47Z")

</div>

Did you get that error running my Minimum Working Example (MWE) above?

I’m not familiar with that error. I imagine it is something inside your `complex_calc` function which is not defined to take a `NamedTuple` (Method 2) or `DataFrameRow` (Method 4). Note that I defined two different `complex_calc` functions and used a different transformation syntax depending on how I defined `complex_calc`. If your existing `complex_calc` works with Methods 1 and 3, then just used those. If you are set on using Method 2 or 4, you could add a new method `complex_calc(row) = complex_calc(row.x, row.y, row.z)` to teach `complex_calc` how to handle a single row argument.
