Bir nechta ustunni qiymatlarni o'z ichiga olgan bitta ustun yordamida tarqating

Kirish ma'lumotlari:

> head(iris[c(48:50, 98:100), 3:5])
    Petal.Length Petal.Width    Species
48           1.4         0.2     setosa
49           1.5         0.2     setosa
50           1.4         0.2     setosa
98           4.3         1.3 versicolor
99           3.0         1.1 versicolor
100          4.1         1.3 versicolor

Chiqish ma'lumotlari:

setosa.Petal.Length versicolor.Petal.Length setosa.Petal.Width versicolor.Petal.Width 
1.4                 4.3                     0.2                1.3
1.5                 3.0                     0.2                1.1
1.4                 4.1                     0.2                1.3

Masalan:

spread(
  iris%>%mutate(n=row_number()), 
  key=Species, 
  value=Petal.Length:Petal.Width) 
  #or c("Petal.Length", "Petal.Width")` 

ishlamaydi

1
% <%>% Group_by (tmp)%>% mutate (indx = row_number ())% bilan birlashishi mumkin (kod, domen, qiymat, >% tarqalishi (tmp, qiymat) bo'lishi mumkin
qo'shib qo'ydi muallif David Arenburg, manba
% <%>% Group_by (tmp)%>% mutate (indx = row_number ())% bilan birlashishi mumkin (kod, domen, qiymat, >% tarqalishi (tmp, qiymat) bo'lishi mumkin
qo'shib qo'ydi muallif David Arenburg, manba
Men sizning tashvishingizni aniq bilmayman. Tezlik yoki xotiradan foydalanishmi? Tezlik qiladigan bo'lsak, shunchaki tidyverse foydalanmang va library (data.table) kabi biror narsani sinab ko'ring; dcast (eritma (setDT (df), "Species"), rowid (turlari, o'zgaruvchi) ~ turlari + variable) o'rniga. Agar xotira ishlatilsa, unda siz sharsimon operatsiyalarni bajarish uchun ba'zi bir yondashuvsiz yondashuvni (masalan lapply ) ishlatishingiz kerak bo'ladi.
qo'shib qo'ydi muallif David Arenburg, manba
Men sizning tashvishingizni aniq bilmayman. Tezlik yoki xotiradan foydalanishmi? Tezlik qiladigan bo'lsak, shunchaki tidyverse foydalanmang va library (data.table) kabi biror narsani sinab ko'ring; dcast (eritma (setDT (df), "Species"), rowid (turlari, o'zgaruvchi) ~ turlari + variable) o'rniga. Agar xotira ishlatilsa, unda siz sharsimon operatsiyalarni bajarish uchun ba'zi bir yondashuvsiz yondashuvni (masalan lapply ) ishlatishingiz kerak bo'ladi.
qo'shib qo'ydi muallif David Arenburg, manba
Men sizning tashvishingizni aniq bilmayman. Tezlik yoki xotiradan foydalanishmi? Tezlik qiladigan bo'lsak, shunchaki tidyverse foydalanmang va library (data.table) kabi biror narsani sinab ko'ring; dcast (eritma (setDT (df), "Species"), rowid (turlari, o'zgaruvchi) ~ turlari + variable) o'rniga. Agar xotira ishlatilsa, unda siz sharsimon operatsiyalarni bajarish uchun ba'zi bir yondashuvsiz yondashuvni (masalan lapply ) ishlatishingiz kerak bo'ladi.
qo'shib qo'ydi muallif David Arenburg, manba
@David Arenburg sizning kodingiz numberOfColumns * numberOfRows uzunligi vektorini ishlab chiqaradi, shuning uchun katta ma'lumotlar to'plamlari uchun muammo paydo bo'ladi
qo'shib qo'ydi muallif Qbik, manba
@David Arenburg sizning kodingiz numberOfColumns * numberOfRows uzunligi vektorini ishlab chiqaradi, shuning uchun katta ma'lumotlar to'plamlari uchun muammo paydo bo'ladi
qo'shib qo'ydi muallif Qbik, manba
@David Arenburg sizning kodingiz numberOfColumns * numberOfRows uzunligi vektorini ishlab chiqaradi, shuning uchun katta ma'lumotlar to'plamlari uchun muammo paydo bo'ladi
qo'shib qo'ydi muallif Qbik, manba

6 javoblar

Buning ortidan kelib, "katta ma'lumotlar to'plamlari" haqida eslayman. Har bir narsaning xushmuomalali muxlisi sifatida doimo katta miqyosda ishlaydigan bo'lsam, men juda yaxshi ko'rsatkichga egaman. Ushbu misol uchun men shunga o'xshash narsani keltirdim. Bu men uchun juda katta ahamiyatga ega edi. Bu esa, asosiy vazifalarni foydalangandir.

Ushbu maqsadlarda split va bazaviy funktsiyalarni ishlatish quvvatsizlikdan qo'rqinchli darajada tezroq bo'ladi. Har qanday odamda bu haqida hech qanday fikr-mulohazalar mavjud emasmi?

Ìrísí ma'lumotlarini replikatsiya qilish katta ma'lumotlar to'plamini soxta qilish uchun o'rnatiladi.

iris_1000 <- plyr::ldply(1:1000, function(i){
  iris
})

Oltita satr 5 ta ustun bilan 150 ming qatorni tashkil qiladi:

dim(iris_1000)
[1] 150000      5

Shunday qilib, bu ma'lumotlar hajmi quyidagicha bo'ladi:

sprintf("%s MB", object.size(iris_1000) * 0.001^2)
[1] "5.401688 MB"

Taqdim etilgan anserni sinov uchun funktsiya chaqiruviga o'girish, lekin o'zgarish faqatgina "Petal" ni emas, balki indeks ustunini tashlabgina qolmasdan va barcha ma'lumotlar ustunlari uchun qo'llaniladi

tidy_fn <- function(){
  iris_1000 %>% 
    gather(key, value, -Species) %>%
    unite(tmp, Species, key, sep=".") %>%
    group_by(tmp) %>%
    mutate(indx = row_number()) %>%
    spread(tmp, value) %>% 
    select(-indx) %>% data.frame
}

Funktsiyani asosan bazaviy paketlardan foydalangan holda ishlatish va kirishni kiritish Ma'lumotlar doirasidan "df" o'zgaruvchisi va ma'lumotlar bo'lishi kerak bo'lgan ustun nomi yoki bizning holatimiz bo'yicha taqsimlanadi

baseish_fn <- function(df, col_split){

  df_split <- split(df, df[[col_split]])

  df_loop <- lapply(names(df_split), function(i){
    iter_df <- df_split[[i]][-which(colnames(df_split[[i]]) == col_split)]
    new_names <- sprintf("%s.%s", i, colnames(iter_df))
    colnames(iter_df) <- new_names
    iter_df
  })
  names(df_loop) <- NULL
  as.data.frame(df_loop)
}

Endi tezkor taqqoslar hayratlanarli bo'ldi ...  Bitta eslatma shundan iboratki, taglik funktsiyasidagi ustun nomlari joylashtiriladi  Keyinchalik taqqoslash uchun qaytib vazifani bajaradigan qaytib kelish tartibiga mos keladi  Buning uchun qadriyatlarni bir marta ishlatish kerak

tidy_val_test <- tidy_fn()

microbenchmark::microbenchmark(
  tidyverse = tidy_fn(),
  `base-ish` = baseish_fn(iris_1000, "Species")[colnames(tidy_val_test)],times = 100L
)

Unit: milliseconds                                                       
      expr       min        lq     mean   median        uq      max neval
 tidyverse 378.46753 419.93116 447.8020 438.5375 466.78367 718.9666   100
  base-ish  76.57918  83.21915  92.8109  87.8329  94.58085 342.2290   100

Va shunga o'xshash mahsulotlarni ishlab chiqarishni ta'minlash uchun:

all(mapply(function(i){
    identical(tidyverse[[i]], `base-ish`[[i]])
},colnames(tidyverse)))

[1] TRUE


head(`base-ish`[1:4,1:5])
  setosa.Sepal.Length setosa.Sepal.Width setosa.Petal.Length setosa.Petal.Width
1                 5.1                3.5                 1.4                0.2
2                 4.9                3.0                 1.4                0.2
3                 4.7                3.2                 1.3                0.2
4                 4.6                3.1                 1.5                0.2
  versicolor.Sepal.Length
1                     7.0
2                     6.4
3                     6.9
4                     5.5
2
qo'shib qo'ydi
Operatsion yoki xotira ishlatish bilan bog'liq OX ga aloqador emasligiga ishonchim komil emas. Men bu ikkovining taassurotlari ostida edim. Va agar siz katta ma'lumotlar to'plamlari bilan ishlasangiz, unda siz shizofrenning sekinlashayotgani ajablanmasligingiz kerak. Bu juda ham ma'lum bo'lgan haqiqat. Tidyverse kunduzgi ishlashning kengligida "oson sintaksis" dir. Tezlik xavotirda bo'lsa, men oddiygina library (data.table) bilan borishim mumkin; dcast (melt (setDT (df), "Species"), rowid (turlar, o'zgaruvchi) ~ Turlar + o'zgarmaydigan)
qo'shib qo'ydi muallif David Arenburg, manba

Buning ortidan kelib, "katta ma'lumotlar to'plamlari" haqida eslayman. Har bir narsaning xushmuomalali muxlisi sifatida doimo katta miqyosda ishlaydigan bo'lsam, men juda yaxshi ko'rsatkichga egaman. Ushbu misol uchun men shunga o'xshash narsani keltirdim. Bu men uchun juda katta ahamiyatga ega edi. Bu esa, asosiy vazifalarni foydalangandir.

Ushbu maqsadlarda split va bazaviy funktsiyalarni ishlatish quvvatsizlikdan qo'rqinchli darajada tezroq bo'ladi. Har qanday odamda bu haqida hech qanday fikr-mulohazalar mavjud emasmi?

Ìrísí ma'lumotlarini replikatsiya qilish katta ma'lumotlar to'plamini soxta qilish uchun o'rnatiladi.

iris_1000 <- plyr::ldply(1:1000, function(i){
  iris
})

Oltita satr 5 ta ustun bilan 150 ming qatorni tashkil qiladi:

dim(iris_1000)
[1] 150000      5

Shunday qilib, bu ma'lumotlar hajmi quyidagicha bo'ladi:

sprintf("%s MB", object.size(iris_1000) * 0.001^2)
[1] "5.401688 MB"

Taqdim etilgan anserni sinov uchun funktsiya chaqiruviga o'girish, lekin o'zgarish faqatgina "Petal" ni emas, balki indeks ustunini tashlabgina qolmasdan va barcha ma'lumotlar ustunlari uchun qo'llaniladi

tidy_fn <- function(){
  iris_1000 %>% 
    gather(key, value, -Species) %>%
    unite(tmp, Species, key, sep=".") %>%
    group_by(tmp) %>%
    mutate(indx = row_number()) %>%
    spread(tmp, value) %>% 
    select(-indx) %>% data.frame
}

Funktsiyani asosan bazaviy paketlardan foydalangan holda ishlatish va kirishni kiritish Ma'lumotlar doirasidan "df" o'zgaruvchisi va ma'lumotlar bo'lishi kerak bo'lgan ustun nomi yoki bizning holatimiz bo'yicha taqsimlanadi

baseish_fn <- function(df, col_split){

  df_split <- split(df, df[[col_split]])

  df_loop <- lapply(names(df_split), function(i){
    iter_df <- df_split[[i]][-which(colnames(df_split[[i]]) == col_split)]
    new_names <- sprintf("%s.%s", i, colnames(iter_df))
    colnames(iter_df) <- new_names
    iter_df
  })
  names(df_loop) <- NULL
  as.data.frame(df_loop)
}

Endi tezkor taqqoslar hayratlanarli bo'ldi ...  Bitta eslatma shundan iboratki, taglik funktsiyasidagi ustun nomlari joylashtiriladi  Keyinchalik taqqoslash uchun qaytib vazifani bajaradigan qaytib kelish tartibiga mos keladi  Buning uchun qadriyatlarni bir marta ishlatish kerak

tidy_val_test <- tidy_fn()

microbenchmark::microbenchmark(
  tidyverse = tidy_fn(),
  `base-ish` = baseish_fn(iris_1000, "Species")[colnames(tidy_val_test)],times = 100L
)

Unit: milliseconds                                                       
      expr       min        lq     mean   median        uq      max neval
 tidyverse 378.46753 419.93116 447.8020 438.5375 466.78367 718.9666   100
  base-ish  76.57918  83.21915  92.8109  87.8329  94.58085 342.2290   100

Va shunga o'xshash mahsulotlarni ishlab chiqarishni ta'minlash uchun:

all(mapply(function(i){
    identical(tidyverse[[i]], `base-ish`[[i]])
},colnames(tidyverse)))

[1] TRUE


head(`base-ish`[1:4,1:5])
  setosa.Sepal.Length setosa.Sepal.Width setosa.Petal.Length setosa.Petal.Width
1                 5.1                3.5                 1.4                0.2
2                 4.9                3.0                 1.4                0.2
3                 4.7                3.2                 1.3                0.2
4                 4.6                3.1                 1.5                0.2
  versicolor.Sepal.Length
1                     7.0
2                     6.4
3                     6.9
4                     5.5
2
qo'shib qo'ydi
Operatsion yoki xotira ishlatish bilan bog'liq OX ga aloqador emasligiga ishonchim komil emas. Men bu ikkovining taassurotlari ostida edim. Va agar siz katta ma'lumotlar to'plamlari bilan ishlasangiz, unda siz shizofrenning sekinlashayotgani ajablanmasligingiz kerak. Bu juda ham ma'lum bo'lgan haqiqat. Tidyverse kunduzgi ishlashning kengligida "oson sintaksis" dir. Tezlik xavotirda bo'lsa, men oddiygina library (data.table) bilan borishim mumkin; dcast (melt (setDT (df), "Species"), rowid (turlar, o'zgaruvchi) ~ Turlar + o'zgarmaydigan)
qo'shib qo'ydi muallif David Arenburg, manba

Buning ortidan kelib, "katta ma'lumotlar to'plamlari" haqida eslayman. Har bir narsaning xushmuomalali muxlisi sifatida doimo katta miqyosda ishlaydigan bo'lsam, men juda yaxshi ko'rsatkichga egaman. Ushbu misol uchun men shunga o'xshash narsani keltirdim. Bu men uchun juda katta ahamiyatga ega edi. Bu esa, asosiy vazifalarni foydalangandir.

Ushbu maqsadlarda split va bazaviy funktsiyalarni ishlatish quvvatsizlikdan qo'rqinchli darajada tezroq bo'ladi. Har qanday odamda bu haqida hech qanday fikr-mulohazalar mavjud emasmi?

Ìrísí ma'lumotlarini replikatsiya qilish katta ma'lumotlar to'plamini soxta qilish uchun o'rnatiladi.

iris_1000 <- plyr::ldply(1:1000, function(i){
  iris
})

Oltita satr 5 ta ustun bilan 150 ming qatorni tashkil qiladi:

dim(iris_1000)
[1] 150000      5

Shunday qilib, bu ma'lumotlar hajmi quyidagicha bo'ladi:

sprintf("%s MB", object.size(iris_1000) * 0.001^2)
[1] "5.401688 MB"

Taqdim etilgan anserni sinov uchun funktsiya chaqiruviga o'girish, lekin o'zgarish faqatgina "Petal" ni emas, balki indeks ustunini tashlabgina qolmasdan va barcha ma'lumotlar ustunlari uchun qo'llaniladi

tidy_fn <- function(){
  iris_1000 %>% 
    gather(key, value, -Species) %>%
    unite(tmp, Species, key, sep=".") %>%
    group_by(tmp) %>%
    mutate(indx = row_number()) %>%
    spread(tmp, value) %>% 
    select(-indx) %>% data.frame
}

Funktsiyani asosan bazaviy paketlardan foydalangan holda ishlatish va kirishni kiritish Ma'lumotlar doirasidan "df" o'zgaruvchisi va ma'lumotlar bo'lishi kerak bo'lgan ustun nomi yoki bizning holatimiz bo'yicha taqsimlanadi

baseish_fn <- function(df, col_split){

  df_split <- split(df, df[[col_split]])

  df_loop <- lapply(names(df_split), function(i){
    iter_df <- df_split[[i]][-which(colnames(df_split[[i]]) == col_split)]
    new_names <- sprintf("%s.%s", i, colnames(iter_df))
    colnames(iter_df) <- new_names
    iter_df
  })
  names(df_loop) <- NULL
  as.data.frame(df_loop)
}

Endi tezkor taqqoslar hayratlanarli bo'ldi ...  Bitta eslatma shundan iboratki, taglik funktsiyasidagi ustun nomlari joylashtiriladi  Keyinchalik taqqoslash uchun qaytib vazifani bajaradigan qaytib kelish tartibiga mos keladi  Buning uchun qadriyatlarni bir marta ishlatish kerak

tidy_val_test <- tidy_fn()

microbenchmark::microbenchmark(
  tidyverse = tidy_fn(),
  `base-ish` = baseish_fn(iris_1000, "Species")[colnames(tidy_val_test)],times = 100L
)

Unit: milliseconds                                                       
      expr       min        lq     mean   median        uq      max neval
 tidyverse 378.46753 419.93116 447.8020 438.5375 466.78367 718.9666   100
  base-ish  76.57918  83.21915  92.8109  87.8329  94.58085 342.2290   100

Va shunga o'xshash mahsulotlarni ishlab chiqarishni ta'minlash uchun:

all(mapply(function(i){
    identical(tidyverse[[i]], `base-ish`[[i]])
},colnames(tidyverse)))

[1] TRUE


head(`base-ish`[1:4,1:5])
  setosa.Sepal.Length setosa.Sepal.Width setosa.Petal.Length setosa.Petal.Width
1                 5.1                3.5                 1.4                0.2
2                 4.9                3.0                 1.4                0.2
3                 4.7                3.2                 1.3                0.2
4                 4.6                3.1                 1.5                0.2
  versicolor.Sepal.Length
1                     7.0
2                     6.4
3                     6.9
4                     5.5
2
qo'shib qo'ydi
Operatsion yoki xotira ishlatish bilan bog'liq OX ga aloqador emasligiga ishonchim komil emas. Men bu ikkovining taassurotlari ostida edim. Va agar siz katta ma'lumotlar to'plamlari bilan ishlasangiz, unda siz shizofrenning sekinlashayotgani ajablanmasligingiz kerak. Bu juda ham ma'lum bo'lgan haqiqat. Tidyverse kunduzgi ishlashning kengligida "oson sintaksis" dir. Tezlik xavotirda bo'lsa, men oddiygina library (data.table) bilan borishim mumkin; dcast (melt (setDT (df), "Species"), rowid (turlar, o'zgaruvchi) ~ Turlar + o'zgarmaydigan)
qo'shib qo'ydi muallif David Arenburg, manba

Devid Arenburg ning ajoyib sharhini ko'rmaguncha javobni yozib qo'ydim va men uning javobiga moslashtirdim.

Buni oldim:

df <- iris %>%
  select(c(starts_with("Petal"), Species)) %>%
  gather(key, value, -Species) %>%
  unite(tmp, Species, key, sep=".") %>%
  group_by(tmp) %>%
  mutate(indx = row_number()) %>%
  spread(tmp, value)

unite() funktsiyasini bilmadim, bu asosiy farq edi.


Obs: Men izoh bera olmaganimdan beri javob sifatida chop etishim kerak edi, va siz javobingizni o'g'irlamoqchi ekanligimni his qilsam, buni o'chirib qo'yishim mumkin.

0
qo'shib qo'ydi

Devid Arenburg ning ajoyib sharhini ko'rmaguncha javobni yozib qo'ydim va men uning javobiga moslashtirdim.

Buni oldim:

df <- iris %>%
  select(c(starts_with("Petal"), Species)) %>%
  gather(key, value, -Species) %>%
  unite(tmp, Species, key, sep=".") %>%
  group_by(tmp) %>%
  mutate(indx = row_number()) %>%
  spread(tmp, value)

unite() funktsiyasini bilmadim, bu asosiy farq edi.


Obs: Men izoh bera olmaganimdan beri javob sifatida chop etishim kerak edi, va siz javobingizni o'g'irlamoqchi ekanligimni his qilsam, buni o'chirib qo'yishim mumkin.

0
qo'shib qo'ydi

Devid Arenburg ning ajoyib sharhini ko'rmaguncha javobni yozib qo'ydim va men uning javobiga moslashtirdim.

Buni oldim:

df <- iris %>%
  select(c(starts_with("Petal"), Species)) %>%
  gather(key, value, -Species) %>%
  unite(tmp, Species, key, sep=".") %>%
  group_by(tmp) %>%
  mutate(indx = row_number()) %>%
  spread(tmp, value)

unite() funktsiyasini bilmadim, bu asosiy farq edi.


Obs: Men izoh bera olmaganimdan beri javob sifatida chop etishim kerak edi, va siz javobingizni o'g'irlamoqchi ekanligimni his qilsam, buni o'chirib qo'yishim mumkin.

0
qo'shib qo'ydi