# Broadcast SubString to subset of DataFrame rows?

**URL:** https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817
**Category:** New to Julia
**Tags:** strings, dataframes, broadcasting
**Created:** [November 2, 2021, 4:48pm UTC](https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817 "2021-11-02T16:48:41Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![blackeneth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blackeneth/32/10353_2.png) [@blackeneth](https://discourse.julialang.org/u/blackeneth)
#### Post date: [November 2, 2021, 4:48pm UTC](https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817/1 "2021-11-02T16:48:41Z")

</div>

Hi,  
Say I have a large DataFrame, with thousands of rows. For some of those rows, I need to parse out a substring and put it in another column. In my case, these rows have “Register(nnnn)” in them, and I need to extract out “nnnn”.

Here is a MWE with just 4 rows:

```julia
dframe = DataFrame(Item = ["Register(1234)","Flow","Register(6789)","Temp"], b = 1:4)

insertcols!(dframe,2,:RegisterID=>"")

rrows = findall(x -> split(x,"(",)[1]=="Register", dframe[:,1])

for i in rrows
    dframe[i,2]=SubString(dframe[i,1],10:13)
end 

```

The output is:

```julia
4×3 DataFrame
 Row │ Item RegisterID b     
     │ String String Int64 
─────┼───────────────────────────────────
   1 │ Register(1234) 1234 1
   2 │ Flow 2
   3 │ Register(6789) 6789 3
   4 │ Temp 4

```

This works fine. However, I’m suspicious there should be some clever way to broadcast that SubString() function to the subset of rows and put the result in column 2 – but I can’t figure out the syntax.

Is it possible?

---

<div class="post-metadata">

### Author: ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)
#### Post date: [November 2, 2021, 4:54pm UTC](https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817/2 "2021-11-02T16:54:23Z")

</div>

Using a regular expression would be more general than parsing out the substring manually.

---

<div class="post-metadata">

### Author: ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)
#### Post date: [November 2, 2021, 6:54pm UTC](https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817/3 "2021-11-02T18:54:31Z")

</div>

Probably you were just missing `Ref` to avoid broadcasting the range of characters:

```julia
dframe[rrows,2] .= SubString.(dframe[rrows,1], Ref(10:13))

```

but here’s a one-liner that implements @Jeff_Emanuel’s advice of using a regular expression:

```julia
select(dframe, :Item, :Item => ByRow(x->only(something(match(r"Register\((.*)\)", x), [""]))) => :RegisterID, :)

```

And here’s a more readable version of the same:

```julia
function get_id(item)
    m = match(r"Register\((.*)\)", item)
    return isnothing(m) ? "" : m[1]
end

select(dframe, :Item, :Item => ByRow(get_id) => :RegisterID, :)

```

---

<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: [November 2, 2021, 6:59pm UTC](https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817/4 "2021-11-02T18:59:43Z")

</div>

Here is the equivalent code in DataFramesMeta.jl

```julia
julia> dframe
4×3 DataFrame
 Row │ Item RegisterID b     
     │ String String Int64 
─────┼───────────────────────────────────
   1 │ Register(1234) 1
   2 │ Flow 2
   3 │ Register(6789) 3
   4 │ Temp 4

julia> @rtransform dframe :RegisterID = begin
           m = match(r"Register\((.*)\)", :Item)
           isnothing(m) ? "" : m[1]
       end
4×3 DataFrame
 Row │ Item RegisterID b     
     │ String AbstractS… Int64 
─────┼───────────────────────────────────
   1 │ Register(1234) 1234 1
   2 │ Flow 2
   3 │ Register(6789) 6789 3
   4 │ Temp 4

```

---

<div class="post-metadata">

### Author: ![blackeneth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blackeneth/32/10353_2.png) [@blackeneth](https://discourse.julialang.org/u/blackeneth)
#### Post date: [November 2, 2021, 8:20pm UTC](https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817/5 "2021-11-02T20:20:27Z")

</div>

Very cool. I’m always impressed how Julia can solve the same problem multiple different ways.

```julia
select(dframe, :Item, :Item => ByRow(x->only(something(match(r"Register\((.*)\)", x), [""]))) => :RegisterID, :)

```

This one’s going to take some study. I’m sure I’ll learn a lot.

---

<div class="post-metadata">

### Author: ![blackeneth](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blackeneth/32/10353_2.png) [@blackeneth](https://discourse.julialang.org/u/blackeneth)
#### Post date: [November 2, 2021, 8:21pm UTC](https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817/6 "2021-11-02T20:21:59Z")

</div>

Haven’t had time to dig into DataFramesMeta yet, but it looks interesting.

---

<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: [November 2, 2021, 8:46pm UTC](https://discourse.julialang.org/t/broadcast-substring-to-subset-of-dataframe-rows/70817/7 "2021-11-02T20:46:03Z")

</div>

It will provide a more simple syntax than DataFrames.jl for many data cleaning operations. No need to learn all of DataFrames before beginning to learn DataFramesMeta.jl
