แยกคอลัมน์เฉพาะจากกรอบข้อมูล


365

ฉันมีเฟรมข้อมูล R ที่มี 6 คอลัมน์และฉันต้องการสร้างดาต้าเฟรมใหม่ที่มีเพียงสามคอลัมน์เท่านั้น

สมมติว่าเฟรมข้อมูลของฉันเป็นdfและฉันต้องการที่จะคอลัมน์สารสกัดA, BและEนี้เป็นเพียงคำสั่งฉันจะคิดออก:

 data.frame(df$A,df$B,df$E)

มีวิธีที่กะทัดรัดกว่านี้อีกไหม?

คำตอบ:


156

ใช้แพ็คเกจdplyrหาก data.frame ของคุณถูกเรียกว่าdf1:

library(dplyr)

df1 %>%
  select(A, B, E)

นอกจากนี้ยังสามารถเขียนได้โดยไม่ต้อง%>%ไปป์เป็น:

select(df1, A, B, E)

2
ด้วยวิวัฒนาการของ Tidyverse ตั้งแต่เริ่มโพสต์คำถามของฉันฉันได้เปลี่ยนคำตอบให้คุณแล้ว
Aren Cambre

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

1
เป็นเวลากว่าสี่ปีแล้วที่คำตอบนี้ส่งมาและรูปแบบยังไม่เปลี่ยนแปลง นิพจน์ที่ไปป์นั้นใช้งานง่ายมากซึ่งเป็นเหตุผลว่าทำไมพวกเขาถึงดึงดูด
Aren Cambre

ฉันจะรันคำสั่งเพิ่มเติมไปยังชุดย่อยนี้ได้อย่างไร เช่นฉันต้องการคำนวณ rowMean: "df1%>% rowMeans (เลือก (A, B, E))" ไม่ทำงาน
Ben

df1 %>% select(A, B, E) %>% rowMeans(.)คุณควรที่จะเข้าด้วยกันท่อเช่น: ดูเอกสารประกอบสำหรับ%>%ไปป์โดยพิมพ์?magrittr::`%>%`
Sam Firke

448

คุณสามารถเซตย่อยโดยใช้เวกเตอร์ของชื่อคอลัมน์ ฉันชอบวิธีนี้มากกว่าคนที่ปฏิบัติต่อชื่อคอลัมน์ราวกับว่าพวกเขาเป็นชื่อวัตถุ (เช่นsubset()) โดยเฉพาะอย่างยิ่งเมื่อเขียนโปรแกรมในฟังก์ชั่นแพคเกจหรือแอปพลิเคชัน

# data for reproducible example
# (and to avoid confusion from trying to subset `stats::df`)
df <- setNames(data.frame(as.list(1:5)), LETTERS[1:5])
# subset
df[,c("A","B","E")]

4
object of type 'closure' is not subsettableที่จะช่วยให้ข้อผิดพลาด
Aren Cambre

24
@ArenCambre: data.frame ของคุณไม่มีชื่อจริงdfdfเป็นฟังก์ชั่นในแพ็คเกจสถิติ
Joshua Ulrich


2
@Cina: เพราะ-"A"เป็นข้อผิดพลาดทางไวยากรณ์ และ?Extractกล่าวว่า " , ยังสามารถเป็นจำนวนเต็มลบบ่งชี้องค์ประกอบ / ชิ้นที่จะปล่อยออกมาจากการเลือก." ij...
Joshua Ulrich

7
มีปัญหากับรูปแบบนี้เป็นเพราะถ้าเราดึงเพียงหนึ่งคอลัมน์ R กลับเวกเตอร์แทน dataframe > df[,c("A")] [1] 1และนี่อาจจะเป็นที่ไม่พึงประสงค์: การใช้subsetไม่มีข้อเสียนี้
David Dorchies

100

นี่คือบทบาทของsubset()ฟังก์ชัน:

> dat <- data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,7),E=c(8,8),F=c(9,9)) 
> subset(dat, select=c("A", "B"))
  A B
1 1 3
2 2 4

เมื่อฉันลองทำสิ่งนี้ด้วยข้อมูลของฉันฉันได้รับข้อผิดพลาด: "ข้อผิดพลาดใน x [j]: ประเภทตัวห้อยที่ไม่ถูกต้อง 'รายการ'" แต่ถ้า c ("A", "B") ไม่ใช่รายการมันคืออะไร ?
Rafael_Espericueta

@Rafael_Espericueta ยากที่จะเดาได้โดยไม่ต้องดูรหัสของคุณ ... แต่c("A", "B")เป็นเวกเตอร์ไม่ใช่รายการ
Stéphane Laurent

มันแปลงกรอบข้อมูลไปยังรายการ
Suat Atan ปริญญาเอก

78

มีสองตัวเลือกที่ชัดเจน: Joshua Ulrich df[,c("A","B","E")]หรือ

df[,c(1,2,5)]

เช่นเดียวกับใน

> df <- data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,7),E=c(8,8),F=c(9,9)) 
> df
  A B C D E F
1 1 3 5 7 8 9
2 2 4 6 7 8 9
> df[,c(1,2,5)]
  A B E
1 1 3 8
2 2 4 8
> df[,c("A","B","E")]
  A B E
1 1 3 8
2 2 4 8

16

ด้วยเหตุผลบางอย่างเท่านั้น

df[, (names(df) %in% c("A","B","E"))]

ทำงานให้ฉัน ไวยากรณ์ข้างต้นทั้งหมดให้ผล "เลือกคอลัมน์ที่ไม่ได้กำหนด"



14

นอกจากนี้คุณยังสามารถใช้sqldfแพคเกจที่ดำเนินการเลือกในกรอบข้อมูล R เป็น:

df1 <- sqldf("select A, B, E from df")

สิ่งนี้จะให้ผลลัพธ์เมื่อเฟรมข้อมูลdf1มีคอลัมน์: A, B, E



1
df<- dplyr::select ( df,A,B,C)

นอกจากนี้คุณสามารถกำหนดชื่ออื่นให้กับข้อมูลที่สร้างขึ้นใหม่

data<- dplyr::select ( df,A,B,C)

0

[ และเซตย่อยไม่สามารถทดแทนได้:

[ จะคืนค่าเวกเตอร์ถ้าเลือกคอลัมน์เดียวเท่านั้น

df = data.frame(a="a",b="b")    

identical(
  df[,c("a")], 
  subset(df,select="a")
) 

identical(
  df[,c("a","b")],  
  subset(df,select=c("a","b"))
)

4
drop=FALSEไม่ได้ถ้าคุณตั้งค่า ตัวอย่าง:df[,c("a"),drop=F]
จนถึง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.