กำลังล้างข้อมูลของรูปแบบที่ไม่สอดคล้องใน R หรือไม่


16

ฉันมักจะจัดการกับข้อมูลการสำรวจที่ยุ่งเหยิงซึ่งต้องมีการทำความสะอาดมากก่อนที่จะสามารถทำสถิติใด ๆ ได้ ฉันเคยทำสิ่งนี้ "ด้วยตนเอง" ใน Excel บางครั้งใช้สูตร Excel และบางครั้งก็ตรวจสอบรายการทีละรายการ ฉันเริ่มทำงานเหล่านี้มากขึ้นเรื่อย ๆ โดยการเขียนสคริปต์เพื่อทำใน R ซึ่งมีประโยชน์มาก (ผลประโยชน์รวมถึงการบันทึกสิ่งที่ทำไปแล้วมีโอกาสผิดพลาดน้อยลงและสามารถนำรหัสมาใช้ใหม่ได้หากชุดข้อมูลเป็น ปรับปรุง)

แต่ยังมีข้อมูลบางประเภทที่ฉันมีปัญหาในการจัดการอย่างมีประสิทธิภาพ ตัวอย่างเช่น:

> d <- data.frame(subject = c(1,2,3,4,5,6,7,8,9,10,11),
+   hours.per.day = c("1", "2 hours", "2 hr", "2hr", "3 hrs", "1-2", "15 min", "30 mins", "a few hours", "1 hr 30 min", "1 hr/week"))
> d
   subject hours.per.day
1        1             1
2        2       2 hours
3        3          2 hr
4        4           2hr
5        5         3 hrs
6        6           1-2
7        7        15 min
8        8       30 mins
9        9   a few hours
10      10   1 hr 30 min
11      11     1 hr/week

hours.per.dayหมายถึงจำนวนชั่วโมงเฉลี่ยต่อวันที่ใช้ไปกับกิจกรรมบางอย่าง แต่สิ่งที่เรามีคือสิ่งที่หัวเรื่องเขียน สมมติว่าฉันตัดสินใจเกี่ยวกับการตอบกลับที่คลุมเครือและฉันต้องการตัวแปร tidied hours.per.day2ดังนี้

   subject hours.per.day hours.per.day2
1        1             1      1.0000000
2        2       2 hours      2.0000000
3        3          2 hr      2.0000000
4        4           2hr      2.0000000
5        5         3 hrs      3.0000000
6        6           1-2      1.5000000
7        7        15 min      0.2500000
8        8       30 mins      0.5000000
9        9   a few hours      3.0000000
10      10   1 hr 30 min      1.5000000
11      11     1 hr/week      0.1428571

สมมติว่าจำนวนผู้ป่วยมีจำนวนมาก (พูด 1,000 คน) และรู้ว่าผู้เรียนมีอิสระที่จะเขียนสิ่งที่พวกเขาชอบวิธีที่ดีที่สุดในการเข้าถึงสิ่งนี้คืออะไร?

คำตอบ:


13

ฉันจะใช้ gsub () เพื่อระบุสตริงที่ฉันรู้แล้วอาจทำส่วนที่เหลือด้วยมือ

test <- c("15min", "15 min", "Maybe a few hours", 
          "4hr", "4hour", "3.5hr", "3-10", "3-10")
new_var <- rep(NA, length(test))

my_sub <- function(regex, new_var, test){
    t2 <- gsub(regex, "\\1", test)
    identified_vars <- which(test != t2)
    new_var[identified_vars] <- as.double(t2[identified_vars])
    return(new_var)    
}

new_var <- my_sub("([0-9]+)[ ]*min", new_var, test)
new_var <- my_sub("([0-9]+)[ ]*(hour|hr)[s]{0,1}", new_var, test)

หากต้องการทำงานกับสิ่งที่คุณต้องเปลี่ยนด้วยมือฉันแนะนำสิ่งนี้:

# Which have we not found
by.hand <- which(is.na(new_var))

# View the unique ones not found
unique(test[by.hand])
# Create a list with the ones
my_interpretation <- list("3-10"= 5, "Maybe a few hours"=3)
for(key_string in names(my_interpretation)){
    new_var[test == key_string] <- unlist(my_interpretation[key_string])
}

สิ่งนี้ให้:

> new_var
[1] 15.0 15.0  3.0  4.0  4.0  3.5  5.0  5.0

Regex อาจจะยุ่งยากเล็กน้อยทุกครั้งที่ฉันทำอะไรกับ regex ฉันจะทำการทดสอบง่ายๆ Se? regex สำหรับคู่มือ นี่คือพฤติกรรมพื้นฐานบางอย่าง:

> # Test some regex
> grep("[0-9]", "12")
[1] 1
> grep("[0-9]", "12a")
[1] 1
> grep("[0-9]$", "12a")
integer(0)
> grep("^[0-9]$", "12a")
integer(0)
> grep("^[0-9][0-9]", "12a")
[1] 1
> grep("^[0-9]{1,2}", "12a")
[1] 1
> grep("^[0-9]*", "a")
[1] 1
> grep("^[0-9]+", "a")
integer(0)
> grep("^[0-9]+", "12222a")
[1] 1
> grep("^(yes|no)$", "yes")
[1] 1
> grep("^(yes|no)$", "no")
[1] 1
> grep("^(yes|no)$", "(yes|no)")
integer(0)
> # Test some gsub, the \\1 matches default or the found text within the ()
> gsub("^(yes|maybe) and no$", "\\1", "yes and no")
[1] "yes"

ขอบคุณสำหรับคำตอบ Max ฉันไม่คุ้นเคยกับการแสดงออกปกติดังนั้นจะต้องเรียนรู้เกี่ยวกับพวกเขา คุณจะให้คำอธิบายสั้น ๆ ว่าคุณจะทำอย่างไรกับการพักผ่อนด้วยมือ? มีวิธีที่ดีกว่าเพียงแค่ทำสิ่งที่ต้องการnew_var[by.hand] <- c(2, 1, ...)ด้วยby.handการเป็นTRUEสำหรับกรณีที่มีการทำด้วยมือ?
mark999

@ mark999: เพิ่มตัวอย่างและคำแนะนำเกี่ยวกับวิธีที่คุณสามารถทำได้ด้วยตนเอง
Max Gordon

1
นิพจน์ทั่วไปมีความสำคัญอย่างยิ่งสำหรับการจัดการข้อมูลทุกประเภท: การล้างข้อมูลตามที่ OP มีหรือสำหรับการแยกข้อมูลจากไฟล์ HTML ฯลฯ (สำหรับ HTML ที่เหมาะสมมีห้องสมุดที่ต้องการXMLช่วยคุณดึงข้อมูล แต่สิ่งนี้ ไม่ทำงานเมื่อ HTML มีรูปแบบไม่ถูกต้อง)
Wayne

6

คำแนะนำของ @ Max เป็นสิ่งที่ดี ดูเหมือนว่าถ้าคุณเขียนอัลกอริทึมที่จดจำตัวเลขรวมถึงคำ / ตัวย่อที่เกี่ยวข้องกับเวลาโดยทั่วไปคุณจะได้รับประโยชน์มากที่สุด นี่จะไม่ใช่รหัสที่สวยงาม แต่มันจะใช้ได้และคุณสามารถปรับปรุงมันได้ตลอดเวลาเมื่อคุณเจอกรณีปัญหา

แต่สำหรับแนวทางที่มีประสิทธิภาพมากขึ้น (และใช้เวลานาน) ลองใช้ Googling "แยกวิเคราะห์สตริงเวลาภาษาธรรมชาติ" บางคนผลการวิจัยที่น่าสนใจนี้เปิดAPI เวลาที่ดีโมดูลหลามและเป็นหนึ่งในหัวข้อชิดมากเช่นหนึ่งเกี่ยวกับเรื่องนี้กองมากเกิน

โดยทั่วไปการแยกวิเคราะห์ภาษาธรรมชาติเป็นปัญหาที่พบบ่อยและคุณควรมองหาวิธีแก้ปัญหาในภาษาอื่นที่ไม่ใช่อาร์คุณสามารถสร้างเครื่องมือในภาษาอื่นที่คุณสามารถเข้าถึงได้โดยใช้ R หรืออย่างน้อยที่สุดคุณก็จะได้แนวคิดที่ดีสำหรับอัลกอริทึมของคุณเอง


4

สำหรับสิ่งนี้ถ้านานพอฉันคิดว่าฉันต้องการรายการนิพจน์ทั่วไปและกฎการแปลงและนำค่าใหม่ไปยังคอลัมน์อื่น (ดังนั้นคุณจึงมีโอกาสที่จะตรวจสอบซ้ำโดยไม่ต้องโหลดข้อมูลดิบ) ; RE จะถูกนำไปใช้เพื่อข้อมูลที่ไม่ได้มีการเปลี่ยนแปลงจนถึงข้อมูลทั้งหมดที่ถูกแปลงหรือกฎทั้งหมดถูกใช้จนหมด อาจเป็นการดีที่สุดที่จะเก็บรายการของค่าตรรกะที่ระบุว่าแถวใดที่ยังไม่ถูกแปลง

แน่นอนว่ากฎบางอย่างนั้นชัดเจนและอาจจัดการกับคดีได้ถึง 80-90% แต่ปัญหาคือมีบางอย่างที่คุณไม่รู้ว่าจะเกิดขึ้นเสมอ (ผู้คนมีความคิดสร้างสรรค์มาก)

จากนั้นคุณต้องมีสคริปต์ที่ต้องผ่านและนำเสนอต้นฉบับของค่ากฎที่ไม่ได้เปลี่ยนรูปแบบโดยยังไม่ชัดเจนให้คุณดูทีละครั้งทำให้คุณมีโอกาสแสดงออกอย่างสม่ำเสมอ (พูด ) เพื่อระบุกรณีเหล่านั้นและให้ใหม่แปลงสำหรับกรณีที่เหมาะสมซึ่งเพิ่มลงในรายการเดิมและนำไปใช้กับแถวที่ยังไม่ได้เปลี่ยนรูปของเวกเตอร์ดั้งเดิมก่อนที่จะตรวจสอบว่ามีกรณีใดเหลืออยู่ที่จะนำเสนอให้คุณ .

มันอาจจะสมเหตุสมผลที่จะมีตัวเลือกในการข้ามกรณี (เพื่อให้คุณสามารถไปที่กรณีที่ง่ายขึ้น) ดังนั้นคุณสามารถหนองในกรณีที่ยากมากจนถึงตอนท้าย

กรณีที่เลวร้ายที่สุดคุณทำด้วยมือ

จากนั้นคุณสามารถเก็บรายการทั้งหมดของกฎที่คุณสร้างเพื่อนำไปใช้อีกครั้งเมื่อข้อมูลเติบโตขึ้นหรือชุดข้อมูลใหม่ที่คล้ายกันเกิดขึ้น

ฉันไม่รู้ว่าเป็นการเข้าใกล้แนวปฏิบัติที่ดีที่สุดจากระยะไกลหรือไม่ (ฉันคิดว่าจะต้องมีสิ่งที่เป็นทางการมากกว่านั้น) แต่ในแง่ของการประมวลผลข้อมูลจำนวนมากอย่างรวดเร็วนั้นอาจมีค่าบางอย่าง


ขอบคุณสำหรับคำตอบเกลน ฟังดูน่าสนใจมาก คุณเห็นว่ามันเป็นข้อได้เปรียบที่ยิ่งใหญ่ที่จะมีการนำเสนอค่าที่ยังไม่ได้ทำการเปลี่ยนแปลงในแต่ละครั้งเมื่อเทียบกับการแสดงเพียงทั้งหมดและดูผลลัพธ์นั้นหรือไม่ ฉันไม่เคยทำอะไรเลยเหมือนมีสิ่งที่นำเสนอทีละคน
mark999

1
@ mark999 ฉันคิดว่ามีทั้งข้อดีและข้อเสียของการนำเสนอครั้งเดียว ข้อดีคือความเรียบง่ายโดยใช้ cat () เพื่อแสดงเวลาที่คลุมเครือและสแกน () เพื่อบันทึกการตีความของคุณในเวลานั้นใช้งานง่าย ข้อเสียคือคุณอาจพลาดภาพใหญ่ของรายการมากมายที่คุณสามารถแก้ไข en masse ด้วยรหัส regex บรรทัดเดียว คุณอาจมีความคิดเกี่ยวกับสิ่งที่คุณหวังว่าจะได้รับ: ถ้าคุณแค่ต้องการแก้ปัญหานี้ให้ทำด้วยมือ หากคุณต้องการเรียนรู้เพิ่มเติมเกี่ยวกับ R ลองรหัสวิธีแก้ไขปัญหา
Ash

ขออภัยที่ไม่มีคำตอบ ฉันเห็นด้วยอย่างกว้าง ๆ กับความคิดเห็นของ Ash
Glen_b

4

R มีบางส่วนมาตรฐานฟังก์ชั่นสำหรับการจัดการข้อมูลซึ่งสามารถนำมาใช้สำหรับการทำความสะอาดข้อมูลในของฐานแพคเกจ ( gsub, transformฯลฯ ) เช่นเดียวกับในแพคเกจของบุคคลที่สามต่างๆเช่นstringr , Reshape , reshape2และplyr ตัวอย่างและแนวทางปฏิบัติที่ดีที่สุดของการใช้งานสำหรับแพคเกจเหล่านี้และฟังก์ชั่นของพวกเขาจะอธิบายไว้ในบทความต่อไปนี้: http://vita.had.co.nz/papers/tidy-data.pdf

นอกจากนี้ R เสนอแพคเกจบางอย่างที่เน้นการทำความสะอาดข้อมูลและการแปลงเป็นพิเศษ:

วิธีการที่ครอบคลุมและสอดคล้องกันในการล้างข้อมูลใน R รวมถึงตัวอย่างและการใช้ชุดแก้ไขและแพ็คเกจแก้ไขข้อผิดพลาดรวมถึงคำอธิบายเวิร์กโฟลว์ ( กรอบ ) ของการล้างข้อมูลใน R มีการนำเสนอในบทความต่อไปนี้ซึ่งฉันขอแนะนำ: http :

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.