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()











ความคิดเห็น

โพสต์ยอดนิยมจากบล็อกนี้

R STUDIO

R for Pipes

R for Data import