Here is a fix with a comment what is changed:
using DataFrames
using .Threads
bd = DataFrame(id = 1:4, pm_0 = [100, 50, 40, 120])
tra = DataFrame(scn = 1:5, tra1 = [0.10, 0.12, 0.14,0.12, 0.14],
tra2 = [0.10, 0.20, 0.12,0.20, 0.12],
tra3 = [0.11, 0.12, 0.14,0.22,0.12])
#Code 1 - No thread
bd2=copy(bd)
result=DataFrame()
l = ReentrantLock() # create lock variable
@threads for k in 1:5
local bd=copy(bd2) # this has to be local to avoid threads sharing the same object
bd[!,"scn"].=k
bd = leftjoin(bd,tra,on = [:scn])
for i in 1:3
bd[!,"pm_$i"].=bd[!,"pm_$(i-1)"].*bd[!,"tra$i"]
end
lock(l) # need to lock for append!
append!(result,bd)
unlock(l)
end
head(result)