str(lib)
## 'data.frame': 72 obs. of 6 variables:
## $ faculty : chr "ศึกษาศาสตร์" "ศึกษาศาสตร์" "ศึกษาศาสตร์" "ศึกษาศาสตร์" ...
## $ month : chr "ม.ค." "ก.พ." "มี.ค." "เม.ย." ...
## $ borrows : int 652 880 668 421 517 227 262 644 903 708 ...
## $ students : int 3200 3200 3200 3200 3200 3200 3200 3200 3200 3200 ...
## $ satisfaction: num 4.1 3.8 3.4 3.6 4 3.9 4 4 3.9 3.4 ...
## $ responses : int 200 202 158 170 162 69 70 241 267 182 ...
head(lib)
## faculty month borrows students satisfaction responses
## 1 ศึกษาศาสตร์ ม.ค. 652 3200 4.1 200
## 2 ศึกษาศาสตร์ ก.พ. 880 3200 3.8 202
## 3 ศึกษาศาสตร์ มี.ค. 668 3200 3.4 158
## 4 ศึกษาศาสตร์ เม.ย. 421 3200 3.6 170
## 5 ศึกษาศาสตร์ พ.ค. 517 3200 4.0 162
## 6 ศึกษาศาสตร์ มิ.ย. 227 3200 3.9 69
# เปรียบเทียบวิธีการนับมากกว่า 1 วิธี
q1_summary <- lib %>%
group_by(faculty) %>%
summarise(
total_borrows = sum(borrows),
students = first(students),
borrows_per_student = round(sum(borrows) / first(students), 2)
) %>%
arrange(desc(borrows_per_student))
# กราฟแสดงการยืมเฉลี่ยต่อนิสิต 1 คน
p1 <- ggplot(q1_summary, aes(x = reorder(faculty, borrows_per_student), y = borrows_per_student)) +
geom_col(fill = "#2b5c8f", width = 0.65) + # ปรับความกว้างแท่ง
geom_text(
aes(label = paste0(borrows_per_student, " เล่ม/คน")),
hjust = -0.15,
size = 3.5,
color = "#222222"
) +
coord_flip() +
scale_y_continuous(limits = c(0, 11.5)) +
labs(
title = "คณะเภสัชศาสตร์ใช้นานและเข้มข้นที่สุดเมื่อเทียบตามสัดส่วนนิสิต (9.14 เล่ม/คน)",
subtitle = "เปรียบเทียบสถิติการยืมหนังสือเฉลี่ยต่อหัวนิสิต ประจำปีการศึกษา 2568",
x = NULL,
y = "จำนวนเล่มที่ยืมต่อนิสิต 1 คน (เล่ม/คน)"
) +
theme_minimal(base_family = "sans") +
theme(
panel.grid.major.y = element_blank(),
plot.title = element_text(face = "bold", size = 13)
)
ggplotly(p1)
คำตอบ (3–4 บรรทัด — “มากที่สุด” ของคุณนับจากอะไร และทำไมเลือกนับแบบนั้น) “มากที่สุด” ในการนำเสนอนี้ นับจาก “ยอดยืมเฉลี่ยต่อหัวนิสิต” (Borrows per Student) คำนวณจาก ยอดยืมรวม / จำนวนนิสิต เมื่อลองนับแบบ ยอดยืมรวม พบว่าคณะวิทยาศาสตร์มากที่สุด (7,393 เล่ม) แต่เพราะมีนิสิตมากถึง 2,400 คน เมื่อปรับตามขนาดคณะพบว่า คณะเภสัชศาสตร์ มียอดยืมจริงเข้มข้นที่สุดถึง 9.14 เล่ม/คน (3,840 เล่ม / 420 คน) จึงเสนอวิธีนี้เพื่อให้ผู้อำนวยการจัดสรรงบซื้อหนังสือได้ตรงกับคณะที่มีความต้องการอ่านต่อนิสิตสูงที่สุด >
month_order <- c("ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.",
"ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค.")
q2_summary <- lib %>%
mutate(month = factor(month, levels = month_order)) %>%
group_by(month) %>%
summarise(total_borrows = sum(borrows))
p2 <- ggplot(q2_summary, aes(x = month, y = total_borrows, group = 1)) +
geom_line(color = "#2b5c8f", size = 1) + # เส้นสีน้ำเงิน
geom_point(color = "#d9534f", size = 2) + # จุดสีแดงเน้นตำแหน่ง
scale_y_continuous(limits = c(0, 4300)) +
labs(
title = "ยอดยืมหนังสือรวมทั้งมหาวิทยาลัยดิ่งต่ำสุดในเดือนมิถุนายน เพียง 966 เล่ม",
subtitle = "แนวโน้มการยืมหนังสือรายเดือน ประจำปีการศึกษา 2568 (สูงสุดในเดือนกันยายน 3,790 เล่ม)",
x = "เดือน (ม.ค. - ธ.ค.)",
y = "จำนวนเล่มที่ยืมรวม (เล่ม)"
) +
theme_minimal(base_family = "sans") +
theme(
panel.grid.minor = element_blank(),
plot.title = element_text(face = "bold", size = 12)
)
ggplotly(p2)
คำตอบ (2 บรรทัด — แนะนำเดือนไหน เพราะอะไร) แนะนำให้จัดกิจกรรมส่งเสริมการอ่านใน เดือนมิถุนายน เนื่องจากมียอดยืมหนังสือรวมทั้งมหาวิทยาลัยต่ำที่สุดเพียง 966 เล่ม การจัดกิจกรรมในช่วงนี้จะช่วยกระตุ้นให้นิสิตกลับมาเข้าใช้บริการห้องสมุด และเพิ่มยอดยืมหนังสือในช่วงซบเซาได้อย่างมีประสิทธิภาพที่สุด >
#สร้าง SharedData
shared_lib <- SharedData$new(lib)
# 2. สร้างตัวกรองคณะ
faculty_filter <- filter_select(
id = "fac_filter",
label = "เลือกคณะที่ต้องการดูข้อมูล:",
sharedData = shared_lib,
group = ~faculty
)
#สร้างกราฟ Interactive Plotly
p3 <- plot_ly(
data = shared_lib,
x = ~month,
y = ~borrows,
type = 'bar',
marker = list(color = '#2b5c8f')
) %>%
layout(
title = "สถิติจำนวนการยืมหนังสือรายเดือนตามคณะที่เลือก",
xaxis = list(
title = "เดือน",
categoryorder = "array",
categoryarray = c("ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค.")
),
yaxis = list(title = "จำนวนการยืม (เล่ม)")
)
#สร้างตาราง DT (เอาปุ่ม Export ออก แต่คง Show entries ไว้ให้กดเลือกแถวได้)
dt3 <- datatable(
shared_lib,
options = list(
pageLength = 6,
lengthMenu = c(6, 12, 24), # ให้คนดูเลือกเปลี่ยน Show 6, 12, 24 entries ได้
autoWidth = TRUE,
dom = 'ltp' # l = Length (Show entries), t = Table, p = Pagination (ซ่อนเฉพาะช่อง Search)
),
colnames = c("คณะ", "เดือน", "จำนวนยืม (เล่ม)", "จำนวนนิสิต", "ความพึงพอใจ", "จำนวนผู้ตอบ"),
rownames = FALSE
)
#แสดงผลมัดรวมผ่าน bscols
bscols(
widths = c(12, 12, 12),
faculty_filter,
p3,
dt3
)
# 1. ดึงข้อมูลคณะเภสัชศาสตร์แบบปลอดภัย (นับจำนวนครั้งที่มีการตอบจากคอลัมน์ satisfaction)
pharm_data <- lib %>%
filter(faculty == "เภสัชศาสตร์") %>%
summarise(
students = first(students),
responses = sum(!is.na(satisfaction)) # นับจำนวนเดือนที่มีผู้ตอบความพึงพอใจจริง
)
# 2. สร้าง dataframe สำหรับทำกราฟ
p4_df <- data.frame(
metric = c("จำนวนนิสิตทั้งหมด", "จำนวนผู้ตอบแบบสอบถามรวม"),
count = c(pharm_data$students, pharm_data$responses)
)
# 3. วาดกราฟสะท้อนปัญหา Sample Size
p4 <- ggplot(p4_df, aes(x = metric, y = count, fill = metric)) +
geom_col(width = 0.5) +
geom_text(aes(label = count), vjust = -0.5, size = 4, fontface = "bold") +
scale_fill_manual(values = c("จำนวนนิสิตทั้งหมด" = "#2b5c8f", "จำนวนผู้ตอบแบบสอบถามรวม" = "#d9534f")) +
scale_y_continuous(limits = c(0, max(p4_df$count) * 1.2)) +
labs(
title = "ข้อสรุปพึงพอใจ 4.7 มีปัญหา: ผู้ตอบแบบสอบถามมีน้อยมากเมื่อเทียบกับนิสิตทั้งหมด",
subtitle = "คณะเภสัชศาสตร์มีนิสิต 420 คน แต่มีผู้ตอบแบบสอบถามรวมเพียงไม่กี่คนเท่านั้น",
x = "",
y = "จำนวน (คน)"
) +
theme_minimal(base_family = "sans") +
theme(legend.position = "none")
ggplotly(p4)
ตัวเลข 4.7 ถูกไหม ผิด (ไม่ถูกต้อง) เหตุผล: เมื่อคำนวณค่าเฉลี่ยความพึงพอใจของคณะเภสัชศาสตร์แบบไม่ถ่วงน้ำหนักจะได้ 4.74 ไม่ใช่ 4.70 พอดี การระบุตัวเลข 4.7 จึงเป็นการปัดเศษที่คลาดเคลื่อนจากข้อมูลจริง >
ข้อสรุปนี้มีปัญหาอะไร (พร้อมตัวเลขยืนยัน) ปัญหาขนาดตัวอย่างน้อยเกินไปอย่างมีนัยสำคัญจนไม่สามารถเป็นตัวแทนได้ (Low Sample Size / Bias) คณะเภสัชศาสตร์มีนิสิตทั้งหมด 420 คน แต่ตลอดทั้งปีมีผู้ตอบแบบสอบถามความพึงพอใจรวมกันเพียง 10 คน เท่านั้น (คิดเป็นอัตราการตอบกลับเพียง 2.38%) >
prompt ที่ใช้ (คัดลอกมาเต็ม ๆ อย่างน้อย 1 อัน) “พอดาวโหลดออกมาแล้วทำไมถึงเป็นแบบนี้ และฉันต้องปรับแก้ตรงไหน”
สิ่งที่แก้จากที่ AI ให้มา และทำไมต้องแก้
สิ่งที่แก้: ปรับถอดปุ่มดาวน์โหลด
(buttons = c('copy', 'csv', 'excel')) ออกจากฟังก์ชัน
datatable() ในตารางข้อ 3 * เหตุผลที่ต้องแก้:
โค้ดที่ AI สร้างให้ตอนแรกมีปุ่มดาวน์โหลดข้อมูล แต่เมื่อทดลองกด Export ออกมาเปิดใน Excel
พบว่าข้อความภาษาไทยกลายเป็นอักขระต่างดาว (เธเธ...)
เนื่องจากปัญหาการเข้ารหัสภาษา (UTF-8 BOM) จึงปรับแก้ด้วยการตัดฟังก์ชันดาวน์โหลดออก
เพื่อให้ตารางเน้นการกรองและโต้ตอบบนแดชบอร์ดได้อย่างสะอาดตาและไม่มีข้อผิดพลาดเรื่องภาษา
>
ถ้า knit ไม่ผ่าน เขียนไว้ตรงนี้ว่าติดตรงไหน