ลบทั้งคอลัมน์ออกจาก data.frame ใน R


267

ไม่มีใครรู้วิธีลบคอลัมน์ทั้งหมดออกจาก data.frame ใน R หรือไม่? เช่นถ้าฉันได้รับ data.frame นี้:

> head(data)
   chr       genome region
1 chr1 hg19_refGene    CDS
2 chr1 hg19_refGene   exon
3 chr1 hg19_refGene    CDS
4 chr1 hg19_refGene   exon
5 chr1 hg19_refGene    CDS
6 chr1 hg19_refGene   exon

และฉันต้องการลบคอลัมน์ที่ 2


1
ซ้ำเป็นไปได้ของการวางคอลัมน์ในกรอบข้อมูล R
jangorecki

คำตอบ:


414

NULLคุณสามารถตั้งค่าให้

> Data$genome <- NULL
> head(Data)
   chr region
1 chr1    CDS
2 chr1   exon
3 chr1    CDS
4 chr1   exon
5 chr1    CDS
6 chr1   exon

ตามที่ระบุไว้ในความคิดเห็นนี่คือความเป็นไปได้อื่น ๆ

Data[2] <- NULL    # Wojciech Sobala
Data[[2]] <- NULL  # same as above
Data <- Data[,-2]  # Ian Fellows
Data <- Data[-2]   # same as above

คุณสามารถลบหลายคอลัมน์ผ่าน:

Data[1:2] <- list(NULL)  # Marek
Data[1:2] <- NULL        # does not work!

ระวังด้วย matrix-subsetting แม้ว่าคุณจะสามารถจบลงด้วยเวกเตอร์:

Data <- Data[,-(2:3)]             # vector
Data <- Data[,-(2:3),drop=FALSE]  # still a data.frame

48
หรือคุณสามารถใช้: ข้อมูล <- ข้อมูล [, - 2]
เอียนเฟลโลว์

2
ด้วยเครื่องหมายจุลภาคคุณสามารถควบคุมอาร์กิวเมนต์ "ปล่อย" ซึ่งเมื่อ FALSE หมายถึง data.frame ยังคง data.frame เมื่อผลลัพธ์ประกอบด้วยเพียงหนึ่งคอลัมน์ - โดยไม่มีเครื่องหมายจุลภาคคุณจะได้รับ data.frame เสมอไม่ว่าจะเป็นหลายคอลัมน์ ไปทางซ้ายหรือเพียงครั้งเดียว - จะถูกละเว้นสำหรับการดึง [-2]
mdsumner

3
@mdsumner Data[-2]ไม่จำเป็นต้องdropโต้แย้งสาเหตุก็มักจะกลับมาจากdata.frame data.frameและฉันคิดว่านี่เป็นวิธีที่ดีกว่าในการแปลคอลัมน์ (และเฉพาะคอลัมน์) ในdata.frame(และเร็วกว่า) ตรวจสอบ: cars[-1](หนึ่งคอลัมน์data.frame) หรือดีกว่า:cars[-(1:2)] data frame with 0 columns and 50 rows
Marek

1
คุณสามารถเขียน Data [2] <- NULL
Wojciech Sobala

11
เคล็ดลับเล็ก ๆ น้อย ๆ : เมื่อถอดหลายคอลัมน์Data[c(1,2)]<-list(NULL)เป็นสิ่งจำเป็น
Marek

69

ในการลบคอลัมน์หนึ่งชื่อขึ้นไปเมื่อชื่อคอลัมน์เป็นที่รู้จัก (ซึ่งต่างกับการพิจารณาในช่วงรันไทม์) ฉันชอบsubset()ไวยากรณ์ เช่นสำหรับ data-frame

df <- data.frame(a=1:3, d=2:4, c=3:5, b=4:6)

เพื่อลบเพียง aคอลัมน์ที่คุณสามารถทำได้

Data <- subset( Data, select = -a )

และเพื่อลบbและdคอลัมน์ที่คุณสามารถทำได้

Data <- subset( Data, select = -c(d, b ) )

คุณสามารถลบคอลัมน์ทั้งหมดระหว่างdและbด้วย:

Data <- subset( Data, select = -c( d : b )

ดังที่ฉันได้กล่าวไว้ข้างต้นวากยสัมพันธ์นี้ใช้ได้เฉพาะเมื่อทราบชื่อคอลัมน์ มันจะไม่ทำงานเมื่อพูดชื่อคอลัมน์ถูกกำหนดโดยทางโปรแกรม (เช่นถูกกำหนดให้กับตัวแปร) ฉันจะทำซ้ำคำเตือนนี้จาก?subsetเอกสาร:

คำเตือน:

นี่คือฟังก์ชั่นอำนวยความสะดวกสำหรับการใช้งานแบบโต้ตอบ สำหรับการเขียนโปรแกรมจะเป็นการดีกว่าที่จะใช้ฟังก์ชั่นการแบ่งย่อยมาตรฐานเช่น '[' และโดยเฉพาะอย่างยิ่งการประเมินที่ไม่ได้มาตรฐานของอาร์กิวเมนต์ 'เซ็ตย่อย' อาจมีผลที่ไม่คาดคิด


26

(เพื่อความสมบูรณ์) หากคุณต้องการลบคอลัมน์ตามชื่อคุณสามารถทำได้:

cols.dont.want <- "genome"
cols.dont.want <- c("genome", "region") # if you want to remove multiple columns

data <- data[, ! names(data) %in% cols.dont.want, drop = F]

รวมถึงdrop = Fทำให้แน่ใจว่าผลลัพธ์จะยังคงอยู่data.frameแม้ว่าจะมีเพียงคอลัมน์เดียวเท่านั้น


22

คำตอบที่โพสต์นั้นดีมากเมื่อทำงานกับdata.frames อย่างไรก็ตามงานเหล่านี้อาจไม่มีประสิทธิภาพจากมุมมองของหน่วยความจำ ด้วยข้อมูลขนาดใหญ่การลบคอลัมน์อาจใช้เวลานานผิดปกติและ / หรือล้มเหลวเนื่องจากout of memoryข้อผิดพลาด แพ็คเกจdata.tableช่วยแก้ไขปัญหานี้กับ:=ผู้ให้บริการ:

library(data.table)
> dt <- data.table(a = 1, b = 1, c = 1)
> dt[,a:=NULL]
     b c
[1,] 1 1

ฉันควรรวบรวมตัวอย่างที่ใหญ่กว่าเพื่อแสดงความแตกต่าง ฉันจะอัปเดตคำตอบนี้ในบางประเด็น


3
data.table::setฟังก์ชั่นที่สามารถใช้กับdata.frameที่จะลบหรือแก้ไขคอลัมน์ได้ทันทีโดยไม่ต้องทำสำเนา ดูที่นี่
GSee

8

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

การใช้dplyr::starwarsข้อมูลตัวอย่างสำหรับความหลากหลายในชื่อคอลัมน์:

library(dplyr)

starwars %>% 
  select(-height) %>%                  # a specific column name
  select(-one_of('mass', 'films')) %>% # any columns named in one_of()
  select(-(name:hair_color)) %>%       # the range of columns from 'name' to 'hair_color'
  select(-contains('color')) %>%       # any column name that contains 'color'
  select(-starts_with('bi')) %>%       # any column name that starts with 'bi'
  select(-ends_with('er')) %>%         # any column name that ends with 'er'
  select(-matches('^v.+s$')) %>%       # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%          # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

นอกจากนี้คุณยังสามารถลดจำนวนคอลัมน์ได้:

starwars %>% 
  select(-2, -(4:10)) # column 2 and columns 4 through 10

คำตอบที่ดี มีแนวคิดใดเกี่ยวกับวิธีวางคอลัมน์ที่มีค่าบางค่าในแถวใดแถวหนึ่ง (ไม่ใช่ในชื่อคอลัมน์ตามที่คุณเสนอไว้ข้างต้น)?
ลอร่า K

df [, - ซึ่ง (sapply (df, ฟังก์ชัน (x) any (x == a)))] โดยที่ df เป็น data frame ของคุณและ a เป็นค่าเฉพาะของคุณเช่น: mtcars [, - ซึ่ง (sapply (mtcars, function (x) any (x == 4)))]
Nanami

7

ด้วยวิธีนี้คุณสามารถลบcolumnและเก็บเข้าไปอีกvariablevariable

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