Около data.table

Π’Π°Π·ΠΈ Π±Π΅Π»Π΅ΠΆΠΊΠ° Ρ‰Π΅ бъдС интСрСсна Π·Π° Ρ‚Π΅Π·ΠΈ, ΠΊΠΎΠΈΡ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° Ρ‚Π°Π±Π»ΠΈΡ‡Π½ΠΈ Π΄Π°Π½Π½ΠΈ Π·Π° R β€” data.table, ΠΈ вСроятно Ρ‰Π΅ сС Π·Π°Ρ€Π°Π΄Π²Π°Ρ‚ Π΄Π° видят Π³ΡŠΠ²ΠΊΠ°Π²ΠΎΡΡ‚Ρ‚Π° Π½Π° Π½Π΅ΠΉΠ½ΠΎΡ‚ΠΎ ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ.

Π’Π΄ΡŠΡ…Π½ΠΎΠ²Π΅Π½ΠΈ ΠΎΡ‚ Π΄ΠΎΠ±ΡŠΡ€ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΊΠΎΠ»Π΅Π³ΠΈ, ΠΈ надявайки сС, Ρ‡Π΅ Π²Π΅Ρ‡Π΅ стС ΠΏΡ€ΠΎΡ‡Π΅Π»ΠΈ Π½Π΅Π³ΠΎΠ²Π°Ρ‚Π° статия, ΠΏΡ€Π΅Π΄Π»Π°Π³Π°ΠΌ Π΄Π° сС Π·Π°Π΄ΡŠΠ»Π±ΠΎΡ‡ΠΈΠΌ Π² оптимизацията Π½Π° ΠΊΠΎΠ΄Π° ΠΈ производитСлността Π½Π° основата Π½Π° data.table.

Π’ΡŠΠ²Π΅Π΄Π΅Π½ΠΈΠ΅: ΠΎΡ‚ΠΊΡŠΠ΄Π΅ ΠΈΠ΄Π²Π° data.table?

Най-Π΄ΠΎΠ±Ρ€Π΅ Π΅ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π½Π΅Ρ‚Π΅ Π·Π°ΠΏΠΎΠ·Π½Π°Π²Π°Π½Π΅Ρ‚ΠΎ с Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ‚Π° ΠΎΡ‚Π΄Π°Π»Π΅Ρ‡, Π° ΠΈΠΌΠ΅Π½Π½ΠΎ, ΠΎΡ‚ структуритС Π΄Π°Π½Π½ΠΈ, ΠΎΡ‚ ΠΊΠΎΠΈΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ ΠΎΠ±Π΅ΠΊΡ‚ΡŠΡ‚ data.table (ΠΏΠΎ-Π½Π°Ρ‚Π°Ρ‚ΡŠΠΊ, Π”Π’).

Масив

Код

## arrays ---------

arrmatr <- array(1:20, c(4,5))

class(arrmatr)

typeof(arrmatr)

is.array(arrmatr)

is.matrix(arrmatr)

Π•Π΄Π½Π° ΠΎΡ‚ Ρ‚Π΅Π·ΠΈ структури Π΅ масив (?base::array). ΠšΠ°ΠΊΡ‚ΠΎ Π² Π΄Ρ€ΡƒΠ³ΠΈ Π΅Π·ΠΈΡ†ΠΈ, масивитС Ρ‚ΡƒΠΊ са ΠΌΠ½ΠΎΠ³ΠΎΠΌΠ΅Ρ€Π½ΠΈ. Π’ΡŠΠΏΡ€Π΅ΠΊΠΈ Ρ‚ΠΎΠ²Π°, интСрСсно Π΅, Ρ‡Π΅ Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π΄Π²ΡƒΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ масив Π·Π°ΠΏΠΎΡ‡Π²Π° Π΄Π° наслСдява свойства ΠΎΡ‚ класа ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° (?base::matrix), Π° Π΅Π΄Π½ΠΎΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ масив, ΠΊΠΎΠ΅Ρ‚ΠΎ ΡΡŠΡ‰ΠΎ Π΅ Π²Π°ΠΆΠ½ΠΎ, Π½Π΅ наслСдява ΠΎΡ‚ Π²Π΅ΠΊΡ‚ΠΎΡ€ (?base::vector).

ΠŸΡ€ΠΈ Ρ‚ΠΎΠ²Π° трябва Π΄Π° сС Ρ€Π°Π·Π±ΠΈΡ€Π°, Ρ‡Π΅ Ρ‚ΠΈΠΏΡŠΡ‚ Π΄Π°Π½Π½ΠΈ, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰ΠΈ сС Π² някакъв ΠΎΠ±Π΅ΠΊΡ‚, слСдва Π΄Π° сС провСрява с функцията base::typeof, която Π²Ρ€ΡŠΡ‰Π° Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΎ описаниС Π½Π° Ρ‚ΠΈΠΏΠ° съгласно R Internals β€” общият ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ» Π½Π° Π΅Π·ΠΈΠΊΠ°, ΡΠ²ΡŠΡ€Π·Π°Π½ с ΠΏΡŠΡ€Π²ΠΎΡ€ΠΎΠ΄Π½ΠΈΡ C.

ΠžΡ‰Π΅ Π΅Π΄Π½Π° ΠΊΠΎΠΌΠ°Π½Π΄Π° Π·Π° опрСдСлянС Π½Π° класа Π½Π° ΠΎΠ±Π΅ΠΊΡ‚Π°, base::class, Π²Ρ€ΡŠΡ‰Π° във случаи Π½Π° Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΈ Π²Π΅ΠΊΡ‚ΠΎΡ€Π΅Π½ Ρ‚ΠΈΠΏ (Ρ‚ΠΎΠΉ сС Ρ€Π°Π·Π»ΠΈΡ‡Π°Π²Π° ΠΏΠΎ ΠΈΠΌΠ΅ ΠΎΡ‚ Π²ΡŠΡ‚Ρ€Π΅ΡˆΠ½ΠΈΡ, Π½ΠΎ позволява ΡΡŠΡ‰ΠΎ Π΄Π° сС Ρ€Π°Π·Π±Π΅Ρ€Π΅ Ρ‚ΠΈΠΏΠ° Π½Π° Π΄Π°Π½Π½ΠΈΡ‚Π΅).

Бписък

ΠžΡ‚ двуизмСрния масив, ΠΊΠΎΠΉΡ‚ΠΎ Π΅ ΠΈ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°, ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ към списък (?base::list).

Код

## lists ------------------

mylist <- as.list(arrmatr)

is.vector(mylist)

is.list(mylist)

ΠŸΡ€ΠΈ Ρ‚ΠΎΠ²Π° стават няколко Π½Π΅Ρ‰Π° навСднъТ:

  • Π’Ρ‚ΠΎΡ€ΠΎΡ‚ΠΎ ΠΈΠ·ΠΌΠ΅Ρ€Π΅Π½ΠΈΠ΅ Π½Π° ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°Ρ‚Π° сС свива, тоСст ΠΏΠΎΠ»ΡƒΡ‡Π°Π²Π°ΠΌΠ΅ Π΅Π΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ ΠΈ списък, ΠΈ Π²Π΅ΠΊΡ‚ΠΎΡ€.
  • Π‘ΠΏΠΈΡΡŠΠΊΡŠΡ‚, Ρ‚Π°ΠΊΠ°, наслСдява ΠΎΡ‚ Ρ‚Π΅Π·ΠΈ класовС. Врябва Π΄Π° сС ΠΈΠΌΠ° ΠΏΡ€Π΅Π΄Π²ΠΈΠ΄, Ρ‡Π΅ Π½Π° Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚Π° Π½Π° списъка Ρ‰Π΅ отговаря Π΅Π΄Π½ΠΎ (скалярно) Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ ΠΎΡ‚ ΠΊΠ»Π΅Ρ‚ΠΊΠ°Ρ‚Π° Π½Π° ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°Ρ‚Π°-ΠΎΠ±Π΅ΠΊΡ‚.

Π‘Π»Π°Π³ΠΎΠ΄Π°Ρ€Π΅Π½ΠΈΠ΅ Π½Π° Ρ„Π°ΠΊΡ‚Π°, Ρ‡Π΅ ΡΠΏΠΈΡΡŠΠΊΡŠΡ‚ Π΅ ΡΡŠΡ‰ΠΎ ΠΈ Π²Π΅ΠΊΡ‚ΠΎΡ€, към Π½Π΅Π³ΠΎ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΏΡ€ΠΈΠ»Π°Π³Π°Ρ‚ ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π·Π° Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΈ.

Π”Π°Ρ‚Π°Ρ„Ρ€Π΅ΠΉΠΌ

ΠžΡ‚ списък, ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° ΠΈΠ»ΠΈ Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ към Π΄Π°Ρ‚Π°Ρ„Ρ€Π΅ΠΉΠΌ (?base::data.frame).

Код

## data.frames ------------

df <- as.data.frame(arrmatr)
df2 <- as.data.frame(mylist)

is.list(df)

df$V6 <- df$V1 + df$V2

Π˜Π½Ρ‚Π΅Ρ€Π΅ΡΠ½ΠΎΡ‚ΠΎ Π² Π½Π΅Π³ΠΎ Π΅: Π΄Π°Ρ‚Π°Ρ„Ρ€Π΅ΠΉΠΌΡŠΡ‚ наслСдява ΠΎΡ‚ списък! ΠšΠΎΠ»ΠΎΠ½ΠΈΡ‚Π΅ Π½Π° Π΄Π°Ρ‚Π°Ρ„Ρ€Π΅ΠΉΠΌΠ° са ΠΊΠ»Π΅Ρ‚ΠΊΠΈ Π½Π° списъка. Π’ΠΎΠ²Π° Ρ‰Π΅ бъдС Π²Π°ΠΆΠ½ΠΎ Π² Π±ΡŠΠ΄Π΅Ρ‰Π΅, ΠΊΠΎΠ³Π°Ρ‚ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠΈΠΌΠΈ Π·Π° ΡΠΏΠΈΡΡŠΡ†ΠΈ.

data.table

МоТС Π΄Π° сС ΠΏΠΎΠ»ΡƒΡ‡ΠΈ Π”Π’ (?data.table::data.table) ΠΎΡ‚ Π΄Π°Ρ‚Π°Ρ„Ρ€Π΅ΠΉΠΌ, списък, Π²Π΅ΠΊΡ‚ΠΎΡ€ ΠΈΠ»ΠΈ ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°. НапримСр, Π΅Ρ‚ΠΎ ΠΊΠ°ΠΊ (in place).

Код

## data.tables -----------------------
library(data.table)

data.table::setDT(df)

is.list(df)

is.data.frame(df)

is.data.table(df)

ПолСзно Π΅, Ρ‡Π΅, ΠΊΠ°ΠΊΡ‚ΠΎ ΠΈ Π΄Π°Ρ‚Π°Ρ„Ρ€Π΅ΠΉΠΌΡŠΡ‚, Π”Π’ наслСдява свойства Π½Π° списъка.

Π”Π’ ΠΈ ΠΏΠ°ΠΌΠ΅Ρ‚

Π’ ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠ΅ ΠΎΡ‚ всички останали ΠΎΠ±Π΅ΠΊΡ‚ΠΈ Π² R base, DΠ’ сС ΠΏΡ€Π΅Π΄Π°Π²Π°Ρ‚ ΠΏΠΎ рСфСрСнция. Ако Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ ΠΊΠΎΠΏΠΈΠ΅ Π² Π½ΠΎΠ²Π° област Π½Π° ΠΏΠ°ΠΌΠ΅Ρ‚Ρ‚Π°, Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ° функция data.table::copy ΠΈΠ»ΠΈ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ сСлСкция ΠΎΡ‚ стария ΠΎΠ±Π΅ΠΊΡ‚.

Код

df2 <- df

df[V1 == 1, V2 := 999]

data.table::fsetdiff(df, df2)

df2 <- data.table::copy(df)

df[V1 == 2, V2 := 999]

data.table::fsetdiff(df, df2)

Π‘ Ρ‚ΠΎΠ²Π° Π²ΡŠΠ²Π΅Π΄Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π°Π²ΡŠΡ€ΡˆΠ²Π°. DΠ’ Π΅ ΠΏΡ€ΠΎΠ΄ΡŠΠ»ΠΆΠ΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° Ρ€Π°Π·Π²ΠΈΡ‚ΠΈΠ΅Ρ‚ΠΎ Π½Π° структуритС ΠΎΡ‚ Π΄Π°Π½Π½ΠΈ Π² R, ΠΊΠΎΠ΅Ρ‚ΠΎ сС ΠΎΡΡŠΡ‰Π΅ΡΡ‚Π²ΡΠ²Π° ΠΏΡ€Π΅Π΄ΠΈΠΌΠ½ΠΎ Ρ‡Ρ€Π΅Π· Ρ€Π°Π·ΡˆΠΈΡ€ΡΠ²Π°Π½Π΅ ΠΈ ускори ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π°Π½ΠΈ Π²ΡŠΡ€Ρ…Ρƒ ΠΎΠ±Π΅ΠΊΡ‚ΠΈ ΠΎΡ‚ клас Π΄Π°Ρ‚Π°Ρ„Ρ€Π΅ΠΉΠΌ. ΠŸΡ€ΠΈ Ρ‚ΠΎΠ²Π° сС Π·Π°ΠΏΠ°Π·Π²Π° наслСдството ΠΎΡ‚ Π΄Ρ€ΡƒΠ³ΠΈ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²ΠΈ.

Някои ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° свойствата Π½Π° data.table

ΠšΠ°Ρ‚ΠΎ ΡΠΏΠΈΡΡŠΠΊβ€¦

Π˜Ρ‚Π΅Ρ€ΠΈΡ€Π°Π½Π΅Ρ‚ΠΎ ΠΏΠΎ Ρ€Π΅Π΄ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° Π΄Π°Ρ‚Π°Ρ„Ρ€Π΅ΠΉΠΌΠ° ΠΈΠ»ΠΈ DΠ’ Π½Π΅ Π΅ Π½Π°ΠΉ-Π΄ΠΎΠ±Ρ€Π°Ρ‚Π° идСя, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΊΠΎΠ΄ΡŠΡ‚ Π½Π° Ρ†ΠΈΠΊΡŠΠ»Π° Π½Π° Π΅Π·ΠΈΠΊΠ° R Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΏΠΎ-Π±Π°Π²Π΅Π½ C, Π½ΠΎ ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°Π½Π΅Ρ‚ΠΎ Π² Ρ†ΠΈΠΊΡŠΠ» ΠΏΠΎ ΠΊΠΎΠ»ΠΎΠ½ΠΈΡ‚Π΅, ΠΊΠΎΠΈΡ‚ΠΎ ΠΎΠ±ΠΈΠΊΠ½ΠΎΠ²Π΅Π½ΠΎ са Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ, Π΅ напълно допустимо. ΠšΠΎΠ³Π°Ρ‚ΠΎ ΠΏΡ€Π΅ΠΌΠΈΠ½Π°Π²Π°ΠΌΠ΅ ΠΏΡ€Π΅Π· ΠΊΠΎΠ»ΠΎΠ½ΠΈΡ‚Π΅, ΠΏΠΎΠΌΠ½ΠΈΠΌ, Ρ‡Π΅ всяка ΠΊΠΎΠ»ΠΎΠ½Π° Π΅ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ ΠΎΡ‚ списък, ΡΡŠΠ΄ΡŠΡ€ΠΆΠ°Ρ‰, ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€Π°Π²ΠΈΠ»ΠΎ, Π²Π΅ΠΊΡ‚ΠΎΡ€. А ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈΡ‚Π΅ с Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΈ са Π΄ΠΎΠ±Ρ€Π΅ Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠ·ΠΈΡ€Π°Π½ΠΈ Π² основнитС Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π½Π° Π΅Π·ΠΈΠΊΠ°. ОсвСн Ρ‚ΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΈΡ‚Π΅ Π·Π° ΠΈΠ·Π±ΠΎΡ€, Ρ‚ΠΈΠΏΠΈΡ‡Π½ΠΈ Π·Π° ΡΠΏΠΈΡΡŠΡ†ΠΈ ΠΈ Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΈ: `[[`, `$`.

Код

## operations on data.tables ------------

#using list properties

df$'V1'[1]

df[['V1']]

df[[1]][1]

sapply(df, class)

sapply(df, function(x) sum(is.na(x)))

ВСкторизация

Ако Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° ΠΏΡ€Π΅ΠΌΠΈΠ½Π΅ΠΌ ΠΏΡ€Π΅Π· Ρ€Π΅Π΄ΠΎΠ²Π΅Ρ‚Π΅ Π½Π° голям DΠ’, Π½Π°ΠΉ-Π΄ΠΎΠ±Ρ€ΠΎΡ‚ΠΎ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Ρ‰Π΅ бъдС написванСто Π½Π° функция с вСкторизация. Но Π°ΠΊΠΎ Ρ‚ΠΎΠ²Π° Π½Π΅ Π΅ възмоТно, трябва Π΄Π° ΠΏΠΎΠΌΠ½ΠΈΠΌ, Ρ‡Π΅ Ρ†ΠΈΠΊΡŠΠ»ΡŠΡ‚ Π²ΡŠΡ‚Ρ€Π΅ DΠ’ Π΅ всС ΠΏΠ°ΠΊ ΠΏΠΎ-Π±ΡŠΡ€Π· ΠΎΡ‚ Ρ†ΠΈΠΊΡŠΠ»Π° Π² R, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ сС изпълнява Π½Π° C.

НСка ΠΏΡ€ΠΎΠ±Π²Π°ΠΌΠ΅ Π½Π° ΠΏΠΎ-голям ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с 100К Ρ€Π΅Π΄Π°. Π©Π΅ ΠΈΠ·Π²Π»Π΅Ρ‡Π΅ΠΌ ΠΏΡŠΡ€Π²Π°Ρ‚Π° Π±ΡƒΠΊΠ²Π° ΠΎΡ‚ Π΄ΡƒΠΌΠΈΡ‚Π΅, входящи Π² ΠΊΠΎΠ»ΠΎΠ½Π°Ρ‚Π°-Π²Π΅ΠΊΡ‚ΠΎΡ€ w.

Актуализирано

Код

library(magrittr)
library(microbenchmark)

## По-голям ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ----

rown <- 100000

dt %
	.[, d := 1 + b + c + rnorm(nrow(.))]

# вСкторизация

microbenchmark({
	dt[
		, first_l := unlist(strsplit(w, split = ' ', fixed = T))[1]
		, by = 1:nrow(dt)
	   ]
})

# Π²Ρ‚ΠΎΡ€ΠΎ

first_l_f %
		do.call(rbind, .) %>%
		`[`(,1)
}

dt[, first_l := NULL]

microbenchmark({
	dt[
		, first_l := .(first_l_f(w))
		]
})

# Ρ‚Ρ€Π΅Ρ‚ΠΎ

first_l_f2 %
		unlist %>%
		matrix(nrow = 3) %>%
		`[`(1,)
}

dt[, first_l := NULL]

microbenchmark({
	dt[
		, first_l := .(first_l_f2(w))
		]
})

ΠŸΡŠΡ€Π²ΠΎ изпълнСниС с ΠΈΡ‚Π΅Ρ€ΠΈΡ€Π°Π½Π΅ ΠΏΠΎ Ρ€Π΅Π΄ΠΎΠ²Π΅Ρ‚Π΅:

Π•Π΄ΠΈΠ½ΠΈΡ†Π°: милисСкунди
expr min
{ dt[, `:=`(first_l, unlist(strsplit(w, split = " ", fixed = T))[1]), by = 1:nrow(dt)] } 439.6217
lq mean median uq max neval
451.9998 460.1593 456.2505 460.9147 621.4042 100

Π’Ρ‚ΠΎΡ€ΠΈ Ρ†ΠΈΠΊΡŠΠ», Π² ΠΊΠΎΠΉΡ‚ΠΎ вСкторизацията сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° Ρ‡Ρ€Π΅Π· ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Π½Π΅ Π½Π° списък Π² ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° ΠΈ Π²Π·ΠΈΠΌΠ°Π½Π΅ Π½Π° Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈ ΠΎΡ‚ сСчСниСто с индСкс 1 (послСдното Π΅ ΠΈΠΌΠ΅Π½Π½ΠΎ вСкторизация). Π©Π΅ сС поправя: вСкторизация Π½Π° Π½ΠΈΠ²ΠΎ функция strsplit, ΠΊΠΎΠΉΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΏΡ€ΠΈΠ΅ΠΌΠ° Π²Π΅ΠΊΡ‚ΠΎΡ€ Π½Π° Π²Ρ…ΠΎΠ΄. Оказва сС, Ρ‡Π΅ ΠΏΡ€ΠΎΡ†Π΅Π΄ΡƒΡ€Π°Ρ‚Π° Π·Π° ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Π½Π΅ Π½Π° списък Π² ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° Π΅ ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎ-Ρ‚Π΅ΠΆΠΊΠ° ΠΎΡ‚ самата вСкторизация, Π½ΠΎ ΠΈ Π² Ρ‚ΠΎΠ·ΠΈ случай Π΅ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»Π½ΠΎ ΠΏΠΎ-Π±ΡŠΡ€Π·Π° ΠΎΡ‚ нСвСкторизирания Π²Π°Ρ€ΠΈΠ°Π½Ρ‚.

Π•Π΄ΠΈΠ½ΠΈΡ†Π°: милисСкунди
expr min lq mean median uq max neval
{ dt[, `:=`(first_l, .(first_l_f(w)))] } 93.07916 112.1381 161.9267 149.6863 185.9893 442.5199 100

УскорСниС ΠΏΠΎ ΠΌΠ΅Π΄ΠΈΠ°Π½Π° Π² 3 ΠΏΡŠΡ‚ΠΈ.

Π’Ρ€Π΅Ρ‚ΠΈ Ρ†ΠΈΠΊΡŠΠ», ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ схСмата Π·Π° ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΡƒΠ²Π°Π½Π΅ Π² ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π° Π΅ ΠΏΡ€ΠΎΠΌΠ΅Π½Π΅Π½Π°.

Π•Π΄ΠΈΠ½ΠΈΡ†Π°: милисСкунди
expr min lq mean median uq max neval
{ dt[, `:=`(first_l, .(first_l_f2(w)))] } 32.60481 34.13679 40.4544 35.57115 42.11975 222.972 100

УскорСниС ΠΏΠΎ ΠΌΠ΅Π΄ΠΈΠ°Π½Π° Π² 13 ΠΏΡŠΡ‚ΠΈ.

Π‘ Ρ‚ΠΎΠ²Π° трябва Π΄Π° сС СкспСримСнтира, ΠΊΠΎΠ»ΠΊΠΎΡ‚ΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ β€” Ρ‚ΠΎΠ»ΠΊΠΎΠ²Π° ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅.

ΠžΡ‰Π΅ Π΅Π΄ΠΈΠ½ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ с вСкторизация, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ ΡΡŠΡ‰ΠΎ ΠΈΠΌΠ° тСкст, Π½ΠΎ Ρ‚ΠΎΠΉ Π΅ близък Π΄ΠΎ Ρ€Π΅Π°Π»Π½ΠΈ условия: Ρ€Π°Π·Π»ΠΈΡ‡Π½Π° дълТина Π½Π° Π΄ΡƒΠΌΠΈΡ‚Π΅, Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΎ количСство Π΄ΡƒΠΌΠΈ. НСобходимо Π΅ Π΄Π° сС ΠΈΠ·Π²Π»Π΅ΠΊΠ°Ρ‚ ΠΏΡŠΡ€Π²ΠΈΡ‚Π΅ 3 Π΄ΡƒΠΌΠΈ. Π•Ρ‚ΠΎ ΠΊΠ°ΠΊ:

Около data.table

Π’ΡƒΠΊ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½Π°Ρ‚Π° функция Π²Π΅Ρ‡Π΅ Π½Π΅ Ρ€Π°Π±ΠΎΡ‚ΠΈ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π²Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡ‚Π΅ ΠΈΠΌΠ°Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Π° дълТина, Π° Π½ΠΈΠ΅ Π·Π°Π΄Π°Π΄ΠΎΡ…ΠΌΠ΅ Ρ€Π°Π·ΠΌΠ΅Ρ€ Π½Π° ΠΌΠ°Ρ‚Ρ€ΠΈΡ†Π°Ρ‚Π°. Π©Π΅ Π³ΠΎ ΠΏΡ€Π΅Ρ€Π°Π±ΠΎΡ‚ΠΈΠΌ, ΠΊΠ°Ρ‚ΠΎ сС ΠΏΠΎΡ€ΠΎΠ²ΠΈΠΌ Π² ΠΈΠ½Ρ‚Π΅Ρ€Π½Π΅Ρ‚.

Код

# fourth

rown <- 100000

words <-
	sapply(
		seq_len(rown)
		, function(x){
			nwords <- rbinom(1, 10, 0.5)
			paste(
				sapply(
					seq_len(nwords)
					, function(x){
						paste(sample(letters, rbinom(1, 10, 0.5), replace = T), collapse = '')
					}
				)
				, collapse = ' '
			)
		}
	)

dt <- 
	data.table(
		w = words
		, a = sample(letters, rown, replace = T)
		, b = runif(rown, -3, 3)
		, c = runif(rown, -3, 3)
		, e = rnorm(rown)
	) %>%
	.[, d := 1 + b + c + rnorm(nrow(.))]

first_l_f3 <- function(sd, n)
{
	l <- strsplit(sd, split = ' ', fixed = T)
	
	maxl <- max(lengths(l))
	
	sapply(l, "length<-", maxl) %>%
		`[`(n,) %>%
		as.character
}

microbenchmark({
	dt[
		, (paste0('w_', 1:3)) := lapply(1:3, function(x) first_l_f3(w, x))
		]
})

dt[
	, (paste0('w_', 1:3)) := lapply(1:3, function(x) first_l_f3(w, x))
	]

Π•Π΄ΠΈΠ½ΠΈΡ†Π°: милисСкунди
expr min lq mean median

{ dt[, `:=`((paste0(Β«w_Β», 1:3)), strsplit(w, split = " ", fixed = T))] } 851.7623 916.071 1054.5 1035.199
uq max neval
1178.738 1356.816 100

Π‘ΠΊΡ€ΠΈΠΏΡ‚ΡŠΡ‚ Ρ€Π°Π±ΠΎΡ‚ΠΈ със срСдна скорост ΠΎΡ‚ 1 сСкунда. НС Π΅ Π·Π»Π΅.

Π‘Π²ΡŠΡ€Π·Π°Π½ΠΈ с Π΅Π΄Π½Π° вСрига…

Π‘ ΠΎΠ±Π΅ΠΊΡ‚ΠΈΡ‚Π΅ Π½Π° DT ΠΌΠΎΠΆΠ΅ Π΄Π° сС Ρ€Π°Π±ΠΎΡ‚ΠΈ, ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΡΠ²ΡŠΡ€Π·Π²Π°Π½Π΅. Π’ΠΎΠ²Π° ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΈΠΊΡ€Π΅ΠΏΠ²Π°Π½Π΅ Π½Π° синтаксис Π½Π° скобки отдясно, Π²ΡΡŠΡ‰Π½ΠΎΡΡ‚, Π·Π°Ρ…Π°Ρ€.

Код

# chaining

res1 <- dt[a == 'a'][sample(.N, 100)]

res2 <- dt[, .N, a][, N]

res3 <- dt[, coefficients(lm(e ~ d))[1], a][, .(letter = a, coef = V1)]

Π’Π΅Ρ‡Π΅ ΠΏΡ€Π΅Π· Ρ‚Ρ€ΡŠΠ±ΠΈΡ‚Π΅β€¦

Подобни ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΈΠ·Π²ΡŠΡ€ΡˆΠ°Ρ‚ Ρ‡Ρ€Π΅Π· piping, ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π° ΠΏΠΎΠ΄ΠΎΠ±Π½ΠΎ, Π½ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»Π½ΠΎ Π΅ ΠΏΠΎ-Π±ΠΎΠ³Π°Ρ‚ΠΎ, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ всякакви ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΈ, Π° Π½Π΅ само DT. Π©Π΅ ΠΈΠ·Π²Π΅Π΄Π΅ΠΌ ΠΊΠΎΠ΅Ρ„ΠΈΡ†ΠΈΠ΅Π½Ρ‚ΠΈΡ‚Π΅ Π½Π° логистичната рСгрСсия Π·Π° Π½Π°ΡˆΠΈΡ‚Π΅ синтСтични Π΄Π°Π½Π½ΠΈ с Ρ€Π΅Π΄ΠΈΡ†Π° Ρ„ΠΈΠ»Ρ‚Ρ€ΠΈ Π·Π° DT.

Код

# piping

samplpe_b <- dt[a %in% head(letters), sample(b, 1)]

res4 <- 
	dt %>%
	.[a %in% head(letters)] %>%
	.[, 
	  {
	  	dt0 <- .SD[1:100]
	  	
	  	quants <- 
	  		dt0[, c] %>%
	  		quantile(seq(0.1, 1, 0.1), na.rm = T)
	  	
	  	.(q = quants)
	  }
	  , .(cond = b > samplpe_b)
	  ] %>%
	glm(
		cond ~ q -1
		, family = binomial(link = "logit")
		, data = .
	) %>%
	summary %>%
	.[[12]]

Бтатистика, машинно ΠΎΠ±ΡƒΡ‡Π΅Π½ΠΈΠ΅ ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ Π² DT

МоТС Π΄Π° сС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Ρ‚ лямбда-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, Π½ΠΎ понякога Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΄Π° Π³ΠΈ ΡΡŠΠ·Π΄Π°Π΄Π΅Ρ‚Π΅ ΠΎΡ‚Π΄Π΅Π»Π½ΠΎ, Π΄Π° Π½Π°ΠΏΠΈΡˆΠ΅Ρ‚Π΅ цялото ΠΏΡ€ΠΎΡƒΡ‡Π²Π°Π½Π΅ Π½Π° Π΄Π°Π½Π½ΠΈ, ΠΈ Π½Π°ΠΏΡ€Π΅Π΄ β€” Ρ‚Π΅ работят Π² DT. ΠŸΡ€ΠΈΠΌΠ΅Ρ€ΡŠΡ‚ Π΅ ΠΎΠ±ΠΎΠ³Π°Ρ‚Π΅Π½ с всички горСспомСнати Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ, плюс няколко ΠΏΠΎΠ»Π΅Π·Π½ΠΈ Π½Π΅Ρ‰Π° ΠΎΡ‚ арсСнала Π½Π° DT (ΠΊΠ°Ρ‚ΠΎ ΠΎΠ±Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ към самия DT Π² DT ΠΏΠΎ рСфСрСнция, понякога въвСдСни Π½Π΅ послСдоватСлно, Π½ΠΎ Ρ‚Π°ΠΊΠ° Ρ‡Π΅ Π΄Π° Π΅ ΡƒΠ΄ΠΎΠ±Π½ΠΎ).

Код

# function

rm(lm_preds)

lm_preds <- function(
	sd, by, n
)
{
	
	if(
		n < 100 | 
		!by[['a']] %in% head(letters, 4)
	   )
	{
		
		res <-
			list(
				low = NA
				, mean = NA
				, high = NA
				, coefs = NA
			)
		
	} else {

		lmm <- 
			lm(
				d ~ c + b
				, data = sd
			)
		
		preds <- 
			stats::predict.lm(
				lmm
				, sd
				, interval = "prediction"
				)
		
		res <-
			list(
				low = preds[, 2]
				, mean = preds[, 1]
				, high = preds[, 3]
				, coefs = coefficients(lmm)
			)
	}

	res
	
}

res5 <- 
	dt %>%
	.[e < 0] %>%
	.[.[, .I[b > 0]]] %>%
	.[, `:=` (
		low = as.numeric(lm_preds(.SD, .BY, .N)[[1]])
		, mean = as.numeric(lm_preds(.SD, .BY, .N)[[2]])
		, high = as.numeric(lm_preds(.SD, .BY, .N)[[3]])
		, coef_c = as.numeric(lm_preds(.SD, .BY, .N)[[4]][1])
		, coef_b = as.numeric(lm_preds(.SD, .BY, .N)[[4]][2])
		, coef_int = as.numeric(lm_preds(.SD, .BY, .N)[[4]][3])
	)
	, a
	] %>%
	.[!is.na(mean), -'e', with = F]


# plot

plo <- 
	res5 %>%
	ggplot +
	facet_wrap(~ a) +
	geom_ribbon(
		aes(
			x = c * coef_c + b * coef_b + coef_int
			, ymin = low
			, ymax = high
			, fill = a
		)
		, size = 0.1
		, alpha = 0.1
	) +
	geom_point(
		aes(
			x = c * coef_c + b * coef_b + coef_int
			, y = mean
			, color = a
		)
		, size = 1
	) +
	geom_point(
		aes(
			x = c * coef_c + b * coef_b + coef_int
			, y = d
		)
		, size = 1
		, color = 'black'
	) +
	theme_minimal()

print(plo)

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Надявам сС, Ρ‡Π΅ успях Π΄Π° създам цялостна, Π½ΠΎ Ρ€Π°Π·Π±ΠΈΡ€Π° сС, Π½Π΅ пълна, ΠΊΠ°Ρ€Ρ‚ΠΈΠ½Π° Π½Π° Ρ‚Π°ΠΊΡŠΠ² ΠΎΠ±Π΅ΠΊΡ‚ ΠΊΠ°Ρ‚ΠΎ data.table, Π·Π°ΠΏΠΎΡ‡Π²Π°ΠΉΠΊΠΈ ΠΎΡ‚ Π½Π΅Π³ΠΎΠ²ΠΈΡ‚Π΅ свойства, ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ с наслСдяванСто ΠΎΡ‚ класовСтС R ΠΈ Π·Π°Π²ΡŠΡ€ΡˆΠ²Π°ΠΉΠΊΠΈ с Π½Π΅Π³ΠΎΠ²ΠΈΡ‚Π΅ ΡƒΠ½ΠΈΠΊΠ°Π»Π½ΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈ ΠΎΠΊΠΎΠ»Π½Π° срСда ΠΎΡ‚ Π΅Π»Π΅ΠΌΠ΅Π½Ρ‚ΠΈ Π½Π° tidyverse. Надявам сС, Ρ‡Π΅ Ρ‚ΠΎΠ²Π° Ρ‰Π΅ Π²ΠΈ ΠΏΠΎΠΌΠΎΠ³Π½Π΅ ΠΏΠΎ-Π΄ΠΎΠ±Ρ€Π΅ Π΄Π° ΠΈΠ·ΡƒΡ‡ΠΈΡ‚Π΅ ΠΈ ΠΏΡ€ΠΈΠ»Π°Π³Π°Ρ‚Π΅ Ρ‚Π°Π·ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° ΠΈ Ρ€Π°Π·Π²Π»Π΅Ρ‡Π΅Π½ΠΈΠ΅.

Около data.table

Бпасибо!

ПълСн код

Код

## load libs ----------------

library(data.table)
library(ggplot2)
library(magrittr)
library(microbenchmark)


## arrays ---------

arrmatr <- array(1:20, c(4,5))

class(arrmatr)

typeof(arrmatr)

is.array(arrmatr)

is.matrix(arrmatr)


## lists ------------------

mylist <- as.list(arrmatr)

is.vector(mylist)

is.list(mylist)


## data.frames ------------

df <- as.data.frame(arrmatr)

is.list(df)

df$V6 <- df$V1 + df$V2


## data.tables -----------------------

data.table::setDT(df)

is.list(df)

is.data.frame(df)

is.data.table(df)

df2 <- df

df[V1 == 1, V2 := 999]

data.table::fsetdiff(df, df2)

df2 <- data.table::copy(df)

df[V1 == 2, V2 := 999]

data.table::fsetdiff(df, df2)


## operations on data.tables ------------

#using list properties

df$'V1'[1]

df[['V1']]

df[[1]][1]

sapply(df, class)

sapply(df, function(x) sum(is.na(x)))


## Bigger example ----

rown <- 100000

dt <- 
	data.table(
		w = sapply(seq_len(rown), function(x) paste(sample(letters, 3, replace = T), collapse = ' '))
		, a = sample(letters, rown, replace = T)
		, b = runif(rown, -3, 3)
		, c = runif(rown, -3, 3)
		, e = rnorm(rown)
	) %>%
	.[, d := 1 + b + c + rnorm(nrow(.))]

# vectorization

# zero - for loop

microbenchmark({
	for(i in 1:nrow(dt))
		{
		dt[
			i
			, first_l := unlist(strsplit(w, split = ' ', fixed = T))[1]
		]
	}
})

# first

microbenchmark({
	dt[
		, first_l := unlist(strsplit(w, split = ' ', fixed = T))[1]
		, by = 1:nrow(dt)
	   ]
})

# second

first_l_f <- function(sd)
{
	strsplit(sd, split = ' ', fixed = T) %>%
		do.call(rbind, .) %>%
		`[`(,1)
}

dt[, first_l := NULL]

microbenchmark({
	dt[
		, first_l := .(first_l_f(w))
		]
})

# third

first_l_f2 <- function(sd)
{
	strsplit(sd, split = ' ', fixed = T) %>%
		unlist %>%
		matrix(nrow = 3) %>%
		`[`(1,)
}

dt[, first_l := NULL]

microbenchmark({
	dt[
		, first_l := .(first_l_f2(w))
		]
})

# fourth

rown <- 100000

words <-
	sapply(
		seq_len(rown)
		, function(x){
			nwords <- rbinom(1, 10, 0.5)
			paste(
				sapply(
					seq_len(nwords)
					, function(x){
						paste(sample(letters, rbinom(1, 10, 0.5), replace = T), collapse = '')
					}
				)
				, collapse = ' '
			)
		}
	)

dt <- 
	data.table(
		w = words
		, a = sample(letters, rown, replace = T)
		, b = runif(rown, -3, 3)
		, c = runif(rown, -3, 3)
		, e = rnorm(rown)
	) %>%
	.[, d := 1 + b + c + rnorm(nrow(.))]

first_l_f3 <- function(sd, n)
{
	l <- strsplit(sd, split = ' ', fixed = T)
	
	maxl <- max(lengths(l))
	
	sapply(l, "length<-", maxl) %>%
		`[`(n,) %>%
		as.character
}

microbenchmark({
	dt[
		, (paste0('w_', 1:3)) := lapply(1:3, function(x) first_l_f3(w, x))
		]
})

dt[
	, (paste0('w_', 1:3)) := lapply(1:3, function(x) first_l_f3(w, x))
	]


# chaining

res1 <- dt[a == 'a'][sample(.N, 100)]

res2 <- dt[, .N, a][, N]

res3 <- dt[, coefficients(lm(e ~ d))[1], a][, .(letter = a, coef = V1)]

# piping

samplpe_b <- dt[a %in% head(letters), sample(b, 1)]

res4 <- 
	dt %>%
	.[a %in% head(letters)] %>%
	.[, 
	  {
	  	dt0 <- .SD[1:100]
	  	
	  	quants <- 
	  		dt0[, c] %>%
	  		quantile(seq(0.1, 1, 0.1), na.rm = T)
	  	
	  	.(q = quants)
	  }
	  , .(cond = b > samplpe_b)
	  ] %>%
	glm(
		cond ~ q -1
		, family = binomial(link = "logit")
		, data = .
	) %>%
	summary %>%
	.[[12]]


# function

rm(lm_preds)

lm_preds <- function(
	sd, by, n
)
{
	
	if(
		n < 100 | 
		!by[['a']] %in% head(letters, 4)
	   )
	{
		
		res <-
			list(
				low = NA
				, mean = NA
				, high = NA
				, coefs = NA
			)
		
	} else {

		lmm <- 
			lm(
				d ~ c + b
				, data = sd
			)
		
		preds <- 
			stats::predict.lm(
				lmm
				, sd
				, interval = "prediction"
				)
		
		res <-
			list(
				low = preds[, 2]
				, mean = preds[, 1]
				, high = preds[, 3]
				, coefs = coefficients(lmm)
			)
	}

	res
	
}

res5 <- 
	dt %>%
	.[e < 0] %>%
	.[.[, .I[b > 0]]] %>%
	.[, `:=` (
		low = as.numeric(lm_preds(.SD, .BY, .N)[[1]])
		, mean = as.numeric(lm_preds(.SD, .BY, .N)[[2]])
		, high = as.numeric(lm_preds(.SD, .BY, .N)[[3]])
		, coef_c = as.numeric(lm_preds(.SD, .BY, .N)[[4]][1])
		, coef_b = as.numeric(lm_preds(.SD, .BY, .N)[[4]][2])
		, coef_int = as.numeric(lm_preds(.SD, .BY, .N)[[4]][3])
	)
	, a
	] %>%
	.[!is.na(mean), -'e', with = F]


# plot

plo <- 
	res5 %>%
	ggplot +
	facet_wrap(~ a) +
	geom_ribbon(
		aes(
			x = c * coef_c + b * coef_b + coef_int
			, ymin = low
			, ymax = high
			, fill = a
		)
		, size = 0.1
		, alpha = 0.1
	) +
	geom_point(
		aes(
			x = c * coef_c + b * coef_b + coef_int
			, y = mean
			, color = a
		)
		, size = 1
	) +
	geom_point(
		aes(
			x = c * coef_c + b * coef_b + coef_int
			, y = d
		)
		, size = 1
		, color = 'black'
	) +
	theme_minimal()

print(plo)

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС с Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster