Создание переменной в зависимости от значения другого с l oop в Julia DataFrame - PullRequest
3 голосов
/ 13 июля 2020

У меня есть следующий фрейм данных Джулии

    grh  anc     anc1     anc2    anc3     anc4     anc5    anc6     anc7  
1     2    5  0.10000  0.12000  0.1800  0.14000  0.15000  0.1900  0.20000   
2     3    7  0.03299  0.05081  0.0355  0.02884  0.03054  0.0332  0.03115   
3     4    3  0.00000  0.00000  0.0000  0.00000  0.00000  0.0000  0.00000   
4     5    4  0.00000  0.00000  0.0000  0.00000  0.00000  0.0000  0.00000   
5     6    1  0.10000  0.10000  0.1000  0.10000  0.10000  0.1000  0.10000 




       anc8     anc9    anc10  
1   0.10000  0.21000  0.24000  
2   0.02177  0.04903  0.04399  
3   0.00000  0.00000  0.00000  
4   0.00000  0.00000  0.00000  
5   0.10000  0.10000  0.10000 

Я хотел бы добавить новые столбцы с forl oop lap1, lap2, .... в зависимости от значений переменной an c. Например, в первой строке anc = 5, поэтому lap1 должен быть равен значению anc5 (0,1500), lap2 равен anc6 (0,1900) ... во второй строке lap1 = anc7 (0,03115), lap2 = anc8 ( 0,02177), ...

Итак, результат должен выглядеть как

grh anc anc1    anc2    anc3    anc4    anc5    anc6    anc7    anc8    anc9    anc10   lap1    lap2    lap3
2   5   0.10000 0.12000 0.18000 0.14000 0.15000 0.19000 0.20000 0.1000  0.21000 0.24000 0.15000 0.19000 0.20000
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
4   3   0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
5   4   0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
6   1   0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000 0.10000

Я все еще очень новичок в Julia, и я был бы очень признателен, если у вас есть идеи. Спасибо

1 Ответ

3 голосов
/ 13 июля 2020

Это способ сделать это:

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]...)
...