ฉันต้องการเร่งความเร็วฟังก์ชันสำหรับการสร้างเมทริกซ์แบบคู่ที่อธิบายจำนวนครั้งที่วัตถุถูกเลือกก่อนและหลังวัตถุอื่นๆ ทั้งหมด ภายในชุดของตำแหน่ง
นี่คือตัวอย่าง 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))
ในแต่ละ Shop
, Fruit
จะถูกเลือกโดยลูกค้าใน Order
ที่กำหนด
ฟังก์ชันต่อไปนี้สร้างเมทริกซ์แบบคู่ 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)
}
โดยที่ mat[m,n]
คือจำนวนครั้งที่ fruits[m]
ถูกเลือก หลัง fruits[n]
และ mat[n,m]
คือจำนวนครั้งที่ fruits[m]
ถูกเลือก ก่อน fruits[n]
จะไม่ถูกบันทึกหากเลือกผลไม้เป็นคู่พร้อมกัน (เช่น ใน Shop
E
)
ดูผลลัพธ์ที่คาดหวัง:
>loop.function(df)
apple orange pear
apple 0 0 2
orange 2 0 1
pear 1 2 0
คุณจะเห็นได้ว่า pear
ถูกเลือกสองครั้งก่อน apple
(ใน Shop
C
และ D
) และ apple
ถูกเลือกหนึ่งครั้งก่อน pear
(ใน Shop
A
)
ฉันกำลังพยายามปรับปรุงความรู้ของฉันเกี่ยวกับการทำให้เป็นเวกเตอร์ โดยเฉพาะอย่างยิ่งในส่วนของการวนซ้ำ ดังนั้นฉันจึงอยากรู้ว่าการวนซ้ำนี้สามารถทำให้เป็นเวกเตอร์ได้อย่างไร
(ฉันรู้สึกว่าอาจมีวิธีแก้ปัญหาโดยใช้ outer()
แต่ความรู้เกี่ยวกับฟังก์ชันเวคเตอร์ของฉันยังมีจำกัดมาก)
อัปเดต
ดูการเปรียบเทียบด้วยข้อมูลจริง times = 10000
สำหรับ loop.function()
, tidyverse.function()
, loop.function2()
, datatable.function()
และ 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
ผลลัพธ์ที่น่าสนใจที่สุดสำหรับฉันอาจเป็นประสิทธิภาพของ tidyverse.function()
จากข้อมูลจริง ฉันจะต้องลองเพิ่มโซลูชัน Rccp
ในภายหลัง - ฉันมีปัญหาในการทำให้พวกเขาทำงานกับข้อมูลจริงได้
ฉันขอขอบคุณสำหรับความสนใจและคำตอบทั้งหมดที่มีให้กับโพสต์นี้ - ความตั้งใจของฉันคือการเรียนรู้และปรับปรุงประสิทธิภาพ และแน่นอนว่ายังมีอะไรอีกมากมายให้เรียนรู้จากความคิดเห็นและวิธีแก้ปัญหาทั้งหมดที่ได้รับ ขอบคุณ!
c(1, 1, 2, 3)
หรือจะเป็นc(1, 1, 1)
เสมอหรือตามลำดับ - person Andrew   schedule 14.07.2020arulesSequence
อาจเกี่ยวข้องกับคุณ ดูเช่น บทช่วยสอนนี้: การขุดรูปแบบตามลำดับใน R - person Henrik   schedule 20.08.2020