แปลงแถวของกรอบข้อมูลเป็นเวกเตอร์


116

ฉันต้องการสร้างเวกเตอร์จากแถวของกรอบข้อมูล แต่ฉันไม่ต้องการที่จะต้องมีชื่อแถวและคอลัมน์ ฉันลองหลายอย่าง ... แต่ไม่มีโชค

นี่คือกรอบข้อมูลของฉัน:

> df <- data.frame(a=c(1,2,4,2),b=c(2,6,2,1),c=c(2.6,8.2,7.5,3))
> df
  a b   c
1 1 2 2.6
2 2 6 8.2
3 4 2 7.5
4 2 1 3.0

ฉันเหนื่อย:

> newV <- as.vector(df[1,])
> newV
  a b   c
1 1 2 2.6

แต่ฉันต้องการบางอย่างที่มีลักษณะเช่นนี้:

> newV <- c( 1,2,2.6)
> newV
[1] 1.0 2.0 2.6

ฉันขอแนะนำให้คุณจัดรูปแบบข้อมูลที่คุณแสดงอย่างถูกต้อง ดูเหมือนว่าคุณจะขาดการแบ่งบรรทัด
Chinmay Patil

ฉันต้องการแถว แถว '1' ไม่ใช่คอลัมน์ 'a'
Joko

มีวิธีนำสิ่งนี้ไปใช้กับทุกแถวของ data frame และจึงรวมเวกเตอร์ทั้งหมดเป็นเวกเตอร์เดียวหรือไม่?
stephanmg

1
@stephanmg: สิ่งที่ชอบ: c(t(as.matrix(df)))?
Andri Signorell

Andri: มันใช้งานได้ดีแม้ว่าฉันจะแก้ปัญหาต่างออกไปได้เช่นกัน
stephanmg

คำตอบ:


154

เมื่อคุณแยกแถวเดียวจากกรอบข้อมูลคุณจะได้รับกรอบข้อมูลหนึ่งแถว แปลงเป็นเวกเตอร์ตัวเลข:

as.numeric(df[1,])

ตามที่ @Roland แนะนำunlist(df[1,])จะแปลง data frame แบบแถวเดียวเป็นเวกเตอร์ตัวเลขโดยไม่ต้องทิ้งชื่อ ดังนั้นจึงunname(unlist(df[1,]))เป็นอีกวิธีหนึ่งที่ชัดเจนกว่าเล็กน้อยเพื่อให้ได้ผลลัพธ์เดียวกัน

ตามที่ @Josh แสดงความคิดเห็นด้านล่างหากคุณมีกรอบข้อมูลที่ไม่ใช่ตัวเลข (ตัวอักษร, ตัวประกอบ, ผสม ... ) คุณต้องas.character(df[1,])ใช้แทน


อาจเป็น +1 (หรือ 0 โหวตลดลง) ให้กับ OP สำหรับการให้รหัสที่แสดงให้เห็นอย่างชัดเจนถึงสิ่งที่พวกเขาต้องการแม้ว่าข้อความและชื่อคำถามจะอ่านไม่ออก
ก็ตาม

@ChinmayPatil ตัวเลือกอื่น ๆ ของพวกเขาคืออะไร? ตัวอย่างโค้ดของพวกเขาทำให้ดูเหมือนว่านั่นคือสิ่งที่พวกเขาต้องการอย่างแน่นอน
Ben Bolker

2
ควรสังเกตว่าเฟรมข้อมูลเป็นเวกเตอร์อยู่แล้วดังนั้นจึงเป็นเวกเตอร์เห็นว่ามันเป็นเวกเตอร์ของโหมด "รายการ" และไม่ทำอะไรเลย เพื่ออำนวยความสะดวกในการทำความเข้าใจกลไกพื้นฐานให้ลองใช้ as.vector (df [1,], mode = "numeric") ซึ่งเป็นตัวอย่าง นี่คือสิ่งที่เป็นตัวเลขทำ

1
ไม่มีปัญหา. ฉันเพียงระบุว่าสำหรับปัญหานี้พวกเขาให้คำตอบเหมือนกันทุกประการ
Ben Bolker

1
อาจมีการเปลี่ยนแปลงในระหว่างนี้ แต่ในวันนี้การยกเลิกรายการอนุญาตให้ทิ้งชื่อ: identical(unlist(df[1,], use.names = FALSE), as.numeric(df[1,])) (และ btw df ยังคงไม่ใช่ชื่อที่เหมาะสมสำหรับ data.frame ... ;-))
Andri Signorell

45

ฉันขอแนะนำunlistซึ่งเก็บชื่อไว้

unlist(df[1,])
  a   b   c 
1.0 2.0 2.6 

is.vector(unlist(df[1,]))
[1] TRUE

หากคุณไม่ต้องการเวกเตอร์ที่มีชื่อ:

unname(unlist(df[1,]))
[1] 1.0 2.0 2.6

7

หากคุณไม่ต้องการเปลี่ยนเป็นตัวเลขคุณสามารถลองสิ่งนี้ได้

> as.vector(t(df)[,1])
[1] 1.0 2.0 2.6

3
สิ่งนี้ไม่สมเหตุสมผลสำหรับฉัน: str(as.vector(t(df)[,1]))คือnum [1:3] 1 2 2.6คือรหัสของคุณจะแปลงผลลัพธ์เป็นเวกเตอร์ตัวเลข ...
Ben Bolker

2
โดยเฉพาะเมื่อคุณใช้t(df)R coerces กรอบข้อมูลเป็นเมทริกซ์ในกรณีนี้คือเมทริกซ์ตัวเลขเนื่องจากองค์ประกอบทั้งหมดเป็นตัวเลข จากนั้น[,1]แยกคอลัมน์แรก (เวกเตอร์ตัวเลขเนื่องจากมิติข้อมูลซ้ำซ้อนจะหลุดโดยอัตโนมัติ) as.vector()เพียงแค่วางชื่อ (ซึ่งคุณสามารถทำได้ด้วยunname())
Ben Bolker

ดูเหมือนว่าจะใช้ได้กับตัวละครเช่นกัน แต่คุณพูดถูกเกี่ยวกับการบีบบังคับ FWIW โซลูชันของฉันจะทำงานกับเฟรมข้อมูลตัวอักษรเช่นกัน .. โดยมีข้อแม้ของข้อมูลทั้งหมดที่ถูกแปลงเป็นตัวอักษร
Chinmay Patil

2
ฉันจะบอกว่าunname(unlist(x))โซลูชันนั้นดีกว่าเล็กน้อย (มีประสิทธิภาพและโปร่งใสกว่า)
Ben Bolker

as.vector(t(df)[,1])ฉันรักมัน ! สิ่งที่ฉันต้องการ!
Uther Pendragon

7

นี่คือdplyrตัวเลือกตาม:

newV = df %>% slice(1) %>% unlist(use.names = FALSE)

# or slightly different:
newV = df %>% slice(1) %>% unlist() %>% unname()

2

โปรดทราบว่าคุณต้องระวังหากแถวของคุณมีปัจจัย นี่คือตัวอย่าง:

df_1 = data.frame(V1 = factor(11:15),
                  V2 = 21:25)
df_1[1,] %>% as.numeric() # you expect 11 21 but it returns 
[1] 1 21

นี่คืออีกตัวอย่างหนึ่ง (โดยค่าเริ่มต้น data.frame () แปลงอักขระเป็นตัวประกอบ)

df_2 = data.frame(V1 = letters[1:5],
                  V2 = 1:5)
df_2[3,] %>% as.numeric() # you expect to obtain c 3 but it returns
[1] 3 3
df_2[3,] %>% as.character() # this won't work neither
[1] "3" "3"

เพื่อป้องกันพฤติกรรมนี้คุณต้องดูแลปัจจัยก่อนที่จะแยกออก:

df_1$V1 = df_1$V1 %>% as.character() %>% as.numeric()
df_2$V1 = df_2$V1 %>% as.character()
df_1[1,] %>% as.numeric()
[1] 11  21
df_2[3,] %>% as.character()
[1] "c" "3"

-3

คอลัมน์ของเฟรมข้อมูลเป็นเวกเตอร์อยู่แล้วคุณเพียงแค่ดึงออกมา โปรดทราบว่าคุณวางคอลัมน์ที่คุณต้องการไว้หลังเครื่องหมายจุลภาคไม่ใช่ข้างหน้า:

> newV <- df[,1]
> newV
[1] 1 2 4 2

ถ้าคุณต้องการแถวจริงๆให้ทำตามที่ Ben พูดและกรุณาใช้คำให้ถูกต้องในอนาคต


แต่ฉันคิดว่า OP ต้องการแถวแรก?
Ben Bolker

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