Это способ сделать это:
5×12 DataFrame
│ Row │ grh │ anc │ anc1 │ anc2 │ anc3 │ anc4 │ anc5 │ anc6 │ anc7 │ anc8 │ anc9 │ anc10 │
│ │ Int64 │ Int64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │
├─────┼───────┼───────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ 1 │ 2 │ 5 │ 0.1 │ 0.12 │ 0.18 │ 0.14 │ 0.15 │ 0.19 │ 0.2 │ 0.1 │ 0.21 │ 0.24 │
│ 2 │ 3 │ 7 │ 0.03299 │ 0.05081 │ 0.0355 │ 0.02884 │ 0.03054 │ 0.0332 │ 0.03115 │ 0.02177 │ 0.04903 │ 0.04399 │
│ 3 │ 4 │ 3 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │
│ 4 │ 5 │ 4 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │
│ 5 │ 6 │ 1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │
julia> transform(df, [r"anc" => ByRow((x...) -> x[x[1]+i]) => "lap$i" for i in 1:3])
5×15 DataFrame
│ Row │ grh │ anc │ anc1 │ anc2 │ anc3 │ anc4 │ anc5 │ anc6 │ anc7 │ anc8 │ anc9 │ anc10 │ lap1 │ lap2 │ lap3 │
│ │ Int64 │ Int64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │
├─────┼───────┼───────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ 1 │ 2 │ 5 │ 0.1 │ 0.12 │ 0.18 │ 0.14 │ 0.15 │ 0.19 │ 0.2 │ 0.1 │ 0.21 │ 0.24 │ 0.15 │ 0.19 │ 0.2 │
│ 2 │ 3 │ 7 │ 0.03299 │ 0.05081 │ 0.0355 │ 0.02884 │ 0.03054 │ 0.0332 │ 0.03115 │ 0.02177 │ 0.04903 │ 0.04399 │ 0.03115 │ 0.02177 │ 0.04903 │
│ 3 │ 4 │ 3 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │
│ 4 │ 5 │ 4 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │
│ 5 │ 6 │ 1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │
(я сохраняю широкий вывод, чтобы не усекать какие-либо столбцы)
В коде я предполагаю, что вы хотите сгенерировать только * Столбцы 1006 *, :lap2
и :lap3
, что означает, что anc
должно быть разрешено принимать самое большее значение 8 (если оно будет 9 или более, вы получите ошибку в коде, так как исходный код не указан. для получения данных).
Ключом к пониманию того, как это работает, является анализ:
[r"anc" => ByRow((x...) -> x[x[1]+i]) => "lap$i" for i in 1:3]
понимание означает, что мы создадим три переменные для i
в диапазоне от 1
до 3
. Итак, давайте исправим, например, i=1
. Теперь:
r"anc"
означает, что мы передадим нашей функции все столбцы, имена которых имеют "anc"
в порядке их появления во фрейме данных (так что сначала будет "anc"
и затем столбцы с суффиксами от 1
до 10
). Эти значения будут переданы как позиционные аргументы - тогда
ByRow((x...) -> x[x[1]+i])
означает, что мы определяем функцию, которая будет передавать данные строка за строкой, (x...) ->
часть означает, что x
будет кортеж, содержащий переданные позиционные аргументы, поскольку мы знаем, что "anc"
- это первый столбец, который мы называем x[1]
, а затем добавляем к нему i
, чтобы получить столбец, который нас интересует; - наконец
"lap$i"
дает нам имя выходной переменной
Другой способ записи:
julia> transform(df, [AsTable(r"anc") => ByRow(x -> x[Symbol("anc", x.anc+i-1)]) => "lap$i" for i in 1:3])
5×15 DataFrame
│ Row │ grh │ anc │ anc1 │ anc2 │ anc3 │ anc4 │ anc5 │ anc6 │ anc7 │ anc8 │ anc9 │ anc10 │ lap1 │ lap2 │ lap3 │
│ │ Int64 │ Int64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │ Float64 │
├─────┼───────┼───────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ 1 │ 2 │ 5 │ 0.1 │ 0.12 │ 0.18 │ 0.14 │ 0.15 │ 0.19 │ 0.2 │ 0.1 │ 0.21 │ 0.24 │ 0.15 │ 0.19 │ 0.2 │
│ 2 │ 3 │ 7 │ 0.03299 │ 0.05081 │ 0.0355 │ 0.02884 │ 0.03054 │ 0.0332 │ 0.03115 │ 0.02177 │ 0.04903 │ 0.04399 │ 0.03115 │ 0.02177 │ 0.04903 │
│ 3 │ 4 │ 3 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │
│ 4 │ 5 │ 4 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │ 0.0 │
│ 5 │ 6 │ 1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │ 0.1 │
Разница в том, что AsTable
делает x
равным быть NamedTuple
, чтобы мы могли индексировать в x
, используя имена столбцов, переданные как x.anc
или как Symbol
s, как в x[Symbol("anc", x.anc+i-1)]
.
РЕДАКТИРОВАТЬ
Если вы хотите увеличить скорость за счет сложности кода, вы можете написать:
m = Matrix(df[!, 3:end])
v = df.anc
insertcols!(df, ["lap$k" => getindex.(Ref(m), axes(df, 1), v .+ k .- 1) for k in 1:3]...)