R for Factors
1 Introduction
ใน R ปัจจัยที่ใช้ในการทำงานกับตัวแปรประเภทตัวแปรที่มีชุดค่าคงที่ที่เป็นไปได้และเป็นที่รู้จัก นอกจากนี้ยังมีประโยชน์เมื่อคุณต้องการแสดงเวกเตอร์ตัวอักษรตามลำดับตัวอักษร
ในอดีตปัจจัยต่างๆสามารถทำงานได้ง่ายกว่าตัวอักษร เป็นผลให้หลายฟังก์ชันในฐาน R โดยอัตโนมัติแปลงตัวอักษรเป็นปัจจัย ซึ่งหมายความว่าปัจจัยต่างๆมักเกิดขึ้นในที่ที่ไม่เป็นประโยชน์ โชคดีที่คุณไม่จำเป็นต้องกังวลเกี่ยวกับเรื่องนี้ใน tidyverse และสามารถมุ่งเน้นไปที่สถานการณ์ที่ปัจจัยต่างๆมีประโยชน์อย่างแท้จริง
สำหรับบริบททางประวัติศาสตร์เพิ่มเติมเกี่ยวกับปัจจัยต่างๆผมขอแนะนำให้ใช้ StringsAsFactors: ประวัติโดยไม่ได้รับอนุญาตโดย Roger Peng และ stringsAsFactors = <sigh> โดย Thomas Lumley
ข้อกำหนดเบื้องต้น
ในการทำงานร่วมกับปัจจัยต่างๆเราจะใช้แพคเกจ forcats ซึ่งมีเครื่องมือในการจัดการกับตัวแปรที่มีความแตกต่างกัน (และเป็นตัวบ่งชี้ของปัจจัยต่างๆ!) เป็นผู้ช่วยเหลือที่หลากหลายสำหรับการทำงานร่วมกับปัจจัยต่างๆ forcats ไม่ได้เป็นส่วนหนึ่งของแกน tidyverse ดังนั้นเราจำเป็นต้องโหลดอย่างชัดเจน
library(tidyverse)
library(forcats)
2 Creating factors
มีตัวแปรที่บันทึกเดือน:
x1 <- c("Dec", "Apr", "Jan", "Mar")
การใช้สตริงเพื่อบันทึกตัวแปรนี้มีสองปัญหา:
1 มีเพียงสิบสองเดือนที่เป็นไปได้และไม่มีอะไรที่ช่วยคุณประหยัดจากการพิมพ์ดีด:
x2 <- c("Dec", "Apr", "Jam", "Mar")
2 ไม่จัดเรียงในลักษณะที่เป็นประโยชน์:
sort(x1)
#> [1] "Apr" "Dec" "Jan" "Mar"
คุณสามารถแก้ไขปัญหาทั้งสองอย่างได้ด้วยปัจจัย ในการสร้างปัจจัยคุณต้องเริ่มต้นด้วยการสร้างรายการระดับที่ถูกต้อง:
month_levels <- c(
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
)
ตอนนี้คุณสามารถสร้างปัจจัย:
y1 <- factor(x1, levels = month_levels)
y1
#> [1] Dec Apr Jan Mar
#> Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
sort(y1)
#> [1] Jan Mar Apr Dec
#> Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
และค่าใด ๆ ที่ไม่อยู่ในชุดจะถูกแปลงเป็น NA โดยอัตโนมัติ
y2 <- factor(x2, levels = month_levels)
y2
#> [1] Dec Apr <NA> Mar
#> Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
ถ้าคุณต้องการคำเตือนคุณสามารถใช้ readr :: parse_factor ():
y2 <- parse_factor(x2, levels = month_levels)
#> Warning: 1 parsing failure.
#> row col expected actual
#> 3 -- value in level set Jam
บางครั้งคุณต้องการให้ลำดับของระดับตรงกับลำดับการปรากฏตัวครั้งแรกในข้อมูล คุณสามารถทำสิ่งนี้
factor(x1)
#> [1] Dec Apr Jan Mar
#> Levels: Apr Dec Jan Mar
เมื่อสร้างปัจจัยโดยกำหนดระดับให้เป็นค่าที่ไม่ซ้ำกัน (x) หรือหลังความเป็นจริงด้วย fct_inorder ():
f1 <- factor(x1, levels = unique(x1))
f1
#> [1] Dec Apr Jan Mar
#> Levels: Dec Apr Jan Mar
f2 <- x1 %>% factor() %>% fct_inorder()
f2
#> [1] Dec Apr Jan Mar
#> Levels: Dec Apr Jan Mar
หากคุณต้องการเข้าถึงชุดของระดับที่ถูกต้องโดยตรงคุณสามารถทำได้โดยใช้ระดับ ():
levels(f2)
#> [1] "Dec" "Apr" "Jan" "Mar"
3 General Social Survey
สำหรับส่วนที่เหลือของบทนี้เราจะมุ่งเน้นไปที่ forcats :: gss_cat เป็นตัวอย่างข้อมูลจาก General Social Survey ซึ่งเป็นแบบสำรวจที่ดำเนินไปเป็นเวลานานของสหรัฐอเมริกาซึ่งดำเนินการโดยองค์กรวิจัยอิสระ NORC ที่มหาวิทยาลัยชิคาโก การสำรวจมีคำถามเป็นพัน ๆ คำถามดังนั้นใน gss_cat ฉันได้เลือกรายละเอียดที่จะแสดงถึงความท้าทายทั่วไปบางอย่างที่คุณจะพบเมื่อทำงานกับปัจจัยต่างๆ
(โปรดจำไว้ว่าเนื่องจากชุดข้อมูลนี้มีให้โดยแพ็กเกจคุณสามารถรับข้อมูลเพิ่มเติมเกี่ยวกับตัวแปรด้วย? gss_cat)
gss_cat
#> # A tibble: 21,483 × 9
#> year marital age race rincome partyid
#> <int> <fctr> <int> <fctr> <fctr> <fctr>
#> 1 2000 Never married 26 White $8000 to 9999 Ind,near rep
#> 2 2000 Divorced 48 White $8000 to 9999 Not str republican
#> 3 2000 Widowed 67 White Not applicable Independent
#> 4 2000 Never married 39 White Not applicable Ind,near rep
#> 5 2000 Divorced 25 White Not applicable Not str democrat
#> 6 2000 Married 25 White $20000 - 24999 Strong democrat
#> # ... with 2.148e+04 more rows, and 3 more variables: relig <fctr>,
#> # denom <fctr>, tvhours <int>
เมื่อปัจจัยต่างๆถูกเก็บไว้ในแหมะคุณไม่สามารถมองเห็นระดับได้อย่างง่ายดาย วิธีหนึ่งที่จะเห็นพวกเขาคือการนับ ():
gss_cat %>%
count(race)
#> # A tibble: 3 × 2
#> race n
#> <fctr> <int>
#> 1 Other 1959
#> 2 Black 3129
#> 3 White 16395
หรือด้วยแผนภูมิแท่ง:
ggplot(gss_cat, aes(race)) +
geom_bar()
ggplot2 จะลดระดับที่ไม่มีค่าใด ๆ คุณสามารถบังคับให้พวกเขาแสดงด้วย:
ggplot(gss_cat, aes(race)) +
geom_bar() +
scale_x_discrete(drop = FALSE)
ระดับเหล่านี้แสดงถึงค่าที่ถูกต้องซึ่งไม่ได้เกิดขึ้นในชุดข้อมูลนี้ น่าเสียดายที่ dplyr ยังไม่มีตัวเลือกการเลื่อน แต่จะเป็นในอนาคต
เมื่อทำงานกับปัจจัยการทำงานสองอย่างมากที่สุดคือการเปลี่ยนลำดับของระดับและการเปลี่ยนค่าของระดับ การดำเนินการดังกล่าวได้อธิบายไว้ในส่วนด้านล่าง
4 Modifying factor order
บ่อยครั้งที่เป็นประโยชน์ในการเปลี่ยนลำดับของระดับปัจจัยในการสร้างภาพ ตัวอย่างเช่นสมมติว่าคุณต้องการสำรวจจำนวนชั่วโมงโดยเฉลี่ยที่ดูโทรทัศน์ต่อวันทั่วทั้งศาสนา:
relig_summary <- gss_cat %>%
group_by(relig) %>%
summarise(
age = mean(age, na.rm = TRUE),
tvhours = mean(tvhours, na.rm = TRUE),
n = n()
)
ggplot(relig_summary, aes(tvhours, relig)) + geom_point()
เป็นการยากที่จะตีความพล็อตนี้เนื่องจากไม่มีรูปแบบโดยรวม เราสามารถปรับปรุงโดยการเรียงลำดับระดับของศาสนาโดยใช้ fct_reorder () fct_reorder () ใช้เวลาสามอาร์กิวเมนต์:
- f ปัจจัยที่มีระดับที่คุณต้องการแก้ไข
- x, เวกเตอร์ตัวเลขที่คุณต้องการใช้เพื่อเรียงลำดับระดับใหม่
- ทางเลือกที่สนุกเป็นฟังก์ชันที่ใช้ถ้าค่าหลายค่า x สำหรับแต่ละค่าของ f ค่าดีฟอลต์คือค่ามัธยฐาน
ggplot(relig_summary, aes(tvhours, fct_reorder(relig, tvhours))) +
geom_point()
การจัดลำดับใหม่ของศาสนาช่วยให้เห็นได้ง่ายขึ้นว่าผู้คนในหมวด "ไม่รู้จัก" ดูทีวีมากขึ้นและศาสนาฮินดูและศาสนาตะวันออกอื่น ๆ ดูน้อยลง
ขณะที่คุณเริ่มทำการแปลงที่ซับซ้อนมากขึ้นฉันขอแนะนำให้ย้ายออกจาก aes () และเข้าสู่ขั้นตอนการ mutate() แยกต่างหาก ตัวอย่างเช่นคุณสามารถเขียนพล็อตด้านบนเป็น:
relig_summary %>%
mutate(relig = fct_reorder(relig, tvhours)) %>%
ggplot(aes(tvhours, relig)) +
geom_point()
จะเกิดอะไรขึ้นหากเราสร้างพล็อตที่คล้ายกันโดยดูว่าอายุเฉลี่ยแตกต่างกันอย่างไรในแต่ละระดับรายได้ที่รายงาน?
rincome_summary <- gss_cat %>%
group_by(rincome) %>%
summarise(
age = mean(age, na.rm = TRUE),
tvhours = mean(tvhours, na.rm = TRUE),
n = n()
)
ggplot(rincome_summary, aes(age, fct_reorder(rincome, age))) + geom_point()
ที่นี่การจัดระดับใหม่โดยพลการไม่ได้เป็นความคิดที่ดี! นั่นเป็นเพราะ rincome มีคำสั่งตามหลักการที่เราไม่ควรทำด้วย สำรอง fct_reorder () สำหรับปัจจัยที่มีระดับสั่งซื้อโดยพลการ
อย่างไรก็ตามไม่ควรดึง "ไม่เหมาะ" ไปด้านหน้าโดยมีระดับพิเศษอื่น ๆ คุณสามารถใช้ fct_relevel () ใช้ปัจจัย f และจำนวนระดับที่คุณต้องการย้ายไปที่ด้านหน้าของบรรทัด
ggplot(rincome_summary, aes(age, fct_relevel(rincome, "Not applicable"))) +
geom_point()
ทำไมคุณถึงคิดว่าอายุเฉลี่ยของ "Not applicable" สูงมาก
การจัดเรียงใหม่อีกประเภทหนึ่งจะเป็นประโยชน์เมื่อคุณวาดเส้นบนพล็อต fct_reorder2 () กำหนดค่าตัวแปรใหม่ด้วยค่า y ที่สัมพันธ์กับค่า x ที่ใหญ่ที่สุด ซึ่งทำให้พล็อตง่ายต่อการอ่านเพราะสีของเส้นตรงกับตำนาน
สุดท้ายสำหรับแปลงแท่งคุณสามารถใช้ fct_infreq () เพื่อสั่งระดับในความถี่ที่เพิ่มขึ้น: นี่เป็นประเภทที่ง่ายที่สุดในการจัดเรียงใหม่เนื่องจากไม่จำเป็นต้องมีตัวแปรพิเศษใด ๆ คุณอาจต้องการรวมกับ fct_rev ()
gss_cat %>%
mutate(marital = marital %>% fct_infreq() %>% fct_rev()) %>%
ggplot(aes(marital)) +
geom_bar()
ความคิดเห็น
แสดงความคิดเห็น