Saya ingin mempercepat fungsi untuk membuat matriks berpasangan yang menjelaskan berapa kali suatu objek dipilih sebelum dan sesudah semua objek lainnya, dalam sekumpulan lokasi.
Ini contohnya df
:
df <- data.frame(Shop = c("A","A","A","B","B","C","C","D","D","D","E","E","E"),
Fruit = c("apple", "orange", "pear",
"orange", "pear",
"pear", "apple",
"pear", "apple", "orange",
"pear", "apple", "orange"),
Order = c(1, 2, 3,
1, 2,
1, 2,
1, 2, 3,
1, 1, 1))
Di setiap Shop
, Fruit
dipilih oleh pelanggan di Order
tertentu.
Fungsi berikut membuat matriks berpasangan m x n
:
loop.function <- function(df){
fruits <- unique(df$Fruit)
nt <- length(fruits)
mat <- array(dim=c(nt,nt))
for(m in 1:nt){
for(n in 1:nt){
## filter df for each pair of fruit
xm <- df[df$Fruit == fruits[m],]
xn <- df[df$Fruit == fruits[n],]
## index instances when a pair of fruit are picked in same shop
mm <- match(xm$Shop, xn$Shop)
## filter xm and xn based on mm
xm <- xm[! is.na(mm),]
xn <- xn[mm[! is.na(mm)],]
## assign number of times fruit[m] is picked after fruit[n] to mat[m,n]
mat[m,n] <- sum(xn$Order < xm$Order)
}
}
row.names(mat) <- fruits
colnames(mat) <- fruits
return(mat)
}
Dimana mat[m,n]
adalah berapa kali fruits[m]
diambil setelah fruits[n]
. Dan mat[n,m]
adalah berapa kali fruits[m]
dipilih sebelum fruits[n]
. Tidak dicatat jika sepasang buah dipetik pada waktu yang sama (misalnya pada Shop
E
).
Lihat keluaran yang diharapkan:
>loop.function(df)
apple orange pear
apple 0 0 2
orange 2 0 1
pear 1 2 0
Anda dapat melihat di sini bahwa pear
dipilih dua kali sebelum apple
(di Shop
C
dan D
), dan apple
dipilih satu kali sebelum pear
(di Shop
A
).
Saya mencoba untuk meningkatkan pengetahuan saya tentang vektorisasi, terutama di tempat loop, jadi saya ingin tahu bagaimana loop ini dapat divektorisasi.
(Saya merasa mungkin ada solusi menggunakan outer()
, namun pengetahuan saya tentang fungsi vektorisasi masih sangat terbatas.)
Perbarui
Lihat pembandingan dengan data nyata times = 10000
untuk loop.function()
, tidyverse.function()
, loop.function2()
, datatable.function()
dan loop.function.TMS()
:
Unit: milliseconds
expr min lq mean median uq max neval cld
loop.function(dat) 186.588600 202.78350 225.724249 215.56575 234.035750 999.8234 10000 e
tidyverse.function(dat) 21.523400 22.93695 26.795815 23.67290 26.862700 295.7456 10000 c
loop.function2(dat) 119.695400 126.48825 142.568758 135.23555 148.876100 929.0066 10000 d
datatable.function(dat) 8.517600 9.28085 10.644163 9.97835 10.766749 215.3245 10000 b
loop.function.TMS(dat) 4.482001 5.08030 5.916408 5.38215 5.833699 77.1935 10000 a
Mungkin hasil yang paling menarik bagi saya adalah performa tidyverse.function()
pada data sebenarnya. Saya harus mencoba menambahkan solusi Rccp
di kemudian hari - Saya mengalami kesulitan membuatnya berfungsi pada data sebenarnya.
Saya mengapresiasi segala ketertarikan dan jawaban yang diberikan pada postingan ini - niat saya adalah untuk belajar dan meningkatkan kinerja, dan tentunya banyak pembelajaran dari semua komentar dan solusi yang diberikan. Terima kasih!
c(1, 1, 2, 3)
atau akan selaluc(1, 1, 1)
atau berurutan? - person Andrew   schedule 14.07.2020arulesSequence
mungkin relevan bagi Anda. Lihat mis. tutorial ini: Penambangan Pola Berurutan di R - person Henrik   schedule 20.08.2020