แปลง data.frame คอลัมน์เป็นเวกเตอร์หรือไม่?


163

ฉันมีชื่อไฟล์เช่น:

a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)

ฉันพยายามต่อไปนี้เพื่อแปลงคอลัมน์ใดคอลัมน์หนึ่งเป็นเวกเตอร์ แต่มันไม่ทำงาน:

avector <- as.vector(aframe['a2'])
class(avector) 
[1] "data.frame"

นี่เป็นทางออกเดียวที่ฉันสามารถทำได้ แต่ฉันคิดว่าต้องมีวิธีที่ดีกว่าในการทำสิ่งนี้:

class(aframe['a2']) 
[1] "data.frame"
avector = c()
for(atmp in aframe['a2']) { avector <- atmp }
class(avector)
[1] "numeric"

หมายเหตุ:คำศัพท์ข้างต้นของฉันอาจไม่ถูกต้องดังนั้นโปรดแก้ไขให้ฉันถ้าเป็นเช่นนั้น ฉันยังคงเรียนรู้โลกแห่งอาร์นอกจากนี้คำอธิบายใด ๆ ที่เกิดขึ้นที่นี่คือความนิยม (เช่นเกี่ยวข้องกับ Python หรือภาษาอื่นจะช่วยได้!)


5
เมื่อคุณเห็นคำตอบการอ่านอย่างใกล้ชิด?'[.data.frame'จะพาคุณไปไกลมาก
joran

คำตอบ:


208

ฉันจะพยายามอธิบายสิ่งนี้โดยไม่ทำผิดพลาด แต่ฉันพนันว่าสิ่งนี้จะดึงดูดความกระจ่างหรือความเห็นสองอย่างในความคิดเห็น

กรอบข้อมูลเป็นรายการ เมื่อคุณเซ็ตย่อย data frame โดยใช้ชื่อคอลัมน์และ[สิ่งที่คุณได้รับคือsublist (หรือ data frame ย่อย) หากคุณต้องการคอลัมน์อะตอมจริงคุณสามารถใช้[[หรือทำให้สับสน (สำหรับฉัน) คุณสามารถทำสิ่งaframe[,2]ที่ส่งคืนเวกเตอร์ไม่ใช่รายการย่อย

ดังนั้นให้ลองใช้ลำดับนี้และสิ่งต่าง ๆ จะชัดเจนขึ้น:

avector <- as.vector(aframe['a2'])
class(avector) 

avector <- aframe[['a2']]
class(avector)

avector <- aframe[,2]
class(avector)

6
+1 สิ่งนี้มีประโยชน์ ฉันเคยชินกับการใช้aframe[,"a2"]เพราะความสามารถในการใช้งานนี้กับทั้งเฟรมข้อมูลและเมทริกซ์ & ดูเหมือนจะได้ผลลัพธ์เดียวกัน - เวกเตอร์
Iterator

8
[..., drop = F]จะส่งคืน data frame เสมอ
hadley

1
นี่เป็นสิ่งที่ดีโดยเฉพาะอย่างยิ่งเนื่องจากdf$xไวยากรณ์ส่งคืนเวกเตอร์ ฉันใช้ไวยากรณ์นี้เป็นเวลานาน แต่เมื่อฉันต้องเริ่มใช้df['name']หรือdf[n]เรียกค้นคอลัมน์ฉันพบปัญหาเมื่อฉันพยายามส่งพวกเขาไปยังฟังก์ชันที่คาดหวังเวกเตอร์ ใช้df[[n]]หรือdf[['x']]ล้างสิ่งที่ถูกต้อง
rensa

8
ทำไมas.vectorดูเหมือนไม่มีเสียงเงียบ ๆ สิ่งนี้ไม่ควรส่งคืนเวกเตอร์หรือล้มเหลวอย่างเห็นได้ชัด?
bli

aframe[['a2']]มีประโยชน์มากกับsfวัตถุเพราะaframe[,"a2"]จะส่งคืนสองคอลัมน์เนื่องจากมีคอลัมน์รูปทรงเรขาคณิตรวมอยู่
Matt


32

คุณสามารถใช้การ$แยก:

class(aframe$a1)
[1] "numeric"

หรือวงเล็บเหลี่ยมสองชั้น:

class(aframe[["a1"]])
[1] "numeric"

21

คุณไม่ต้องการas.vector()แต่คุณต้องการการจัดทำดัชนีที่ถูกต้อง:avector <- aframe[ , "a2"]

อีกสิ่งหนึ่งที่ต้องระวังคือdrop=FALSEตัวเลือก[:

R> aframe <- data.frame(a1=c1:5, a2=6:10, a3=11:15)
R> aframe
  a1 a2 a3
1  1  6 11
2  2  7 12
3  3  8 13
4  4  9 14
5  5 10 15
R> avector <- aframe[, "a2"]
R> avector
[1]  6  7  8  9 10
R> avector <- aframe[, "a2", drop=FALSE]
R> avector
  a2
1  6
2  7
3  8
4  9
5 10
R> 

4
+1: การเตือนความจำdrop=FALSEมีประโยชน์ - สิ่งนี้ช่วยฉันในกรณีที่ฉันอาจเลือกคอลัมน์ N จาก data.frame ในกรณีที่ N = 1
Iterator

ฉันใช้สิ่งนี้เมื่อฉันไม่สามารถคาดการณ์จำนวนคอลัมน์ที่เลือกและในกรณีที่มีคอลัมน์หนึ่งเกิดขึ้นผลลัพธ์จะยังคงถูกส่งผ่านเป็น data.frame พร้อมคอลัมน์ n เวกเตอร์อาจโยนประแจลิงเข้าไปในฟังก์ชั่นตามบรรทัด
Roman Luštrik

11

ข้อดีอีกอย่างของการใช้โอเปอเรเตอร์ '[[' คือการใช้งานกับ data.frame และ data.table ดังนั้นหากฟังก์ชั่นจะต้องมีการเรียกใช้สำหรับ data.frame และ data.table และคุณต้องการที่จะดึงคอลัมน์จากมันเป็นเวกเตอร์แล้ว

data[["column_name"]] 

ดีที่สุด


8

คุณสามารถลองสิ่งนี้ -

as.vector(unlist(aframe$a2))

identicalนี้เป็นสิ่งที่ดีถ้าคุณต้องการเปรียบเทียบสองคอลัมน์โดยใช้
p-robot

5

หากคุณเพียงแค่ใช้ตัวดำเนินการแยกมันจะทำงาน โดยค่าเริ่มต้น [] ตั้งค่าตัวเลือกdrop=TRUEซึ่งเป็นสิ่งที่คุณต้องการที่นี่ ดู?'['รายละเอียดเพิ่มเติมได้ที่

>  a1 = c(1, 2, 3, 4, 5)
>  a2 = c(6, 7, 8, 9, 10)
>  a3 = c(11, 12, 13, 14, 15)
>  aframe = data.frame(a1, a2, a3)
> aframe[,'a2']
[1]  6  7  8  9 10
> class(aframe[,'a2'])
[1] "numeric"


3
a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)
avector <- as.vector(aframe['a2'])

avector<-unlist(avector)
#this will return a vector of type "integer"

2

ฉันใช้รายการเพื่อกรองข้อมูลโดยระบุว่าพวกเขามีค่า% เป็น% ในรายการหรือไม่

ฉันสร้างรายการด้วยตนเองด้วยการส่งออก 1 คอลัมน์ข้อมูลไปยัง Excel โดยที่ฉันจะเพิ่ม "" รอบแต่ละองค์ประกอบก่อนที่จะวางลงใน R: รายการ <- c ("el1", "el2", ... ) ซึ่งมักจะเป็น ตามด้วย FilteredData <- ชุดย่อย (ข้อมูล, คอลัมน์% ในรายการ%)

หลังจากค้นหา stackoverflow และไม่พบวิธีที่ง่ายในการแปลง 1 คอลัมน์ข้อมูลลงในรายการตอนนี้ฉันกำลังโพสต์การสนับสนุน stackoverflow ครั้งแรกของฉัน:

# assuming you have a 1 column dataframe called "df"
list <- c()
for(i in 1:nrow(df)){
  list <- append(list, df[i,1])
}
View(list)
# This list is not a dataframe, it is a list of values
# You can filter a dataframe using "subset([Data], [Column] %in% list")

1

นอกจากนี้เรายังสามารถแปลงคอลัมน์ data.frame โดยทั่วไปเป็นเวกเตอร์ง่าย ๆ as.vectorไม่เพียงพอเนื่องจากยังคงคลาส data.frame และโครงสร้างดังนั้นเราจึงต้องดึงองค์ประกอบแรก (และเท่านั้น):

df_column_object <- aframe[,2]
simple_column <- df_column_object[[1]]

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

หรือมิฉะนั้นคุณสามารถอ่านชื่อคอลัมน์จากคอลัมน์ก่อนแล้วจึงใส่ชื่อลงในรหัสในโซลูชันอื่น

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