2010-02-17 42 views

Trả lời

56

Như Oscar Wilde nói

Tính nhất quán là nơi ẩn náu cuối cùng của unimaginative.

R là ngôn ngữ phát triển hơn là được thiết kế, vì vậy những điều này xảy ra. names()colnames() làm việc trên một data.frame nhưng names() không hoạt động trên một ma trận:

R> DF <- data.frame(foo=1:3, bar=LETTERS[1:3]) 
R> names(DF) 
[1] "foo" "bar" 
R> colnames(DF) 
[1] "foo" "bar" 
R> M <- matrix(1:9, ncol=3, dimnames=list(1:3, c("alpha","beta","gamma"))) 
R> names(M) 
NULL 
R> colnames(M) 
[1] "alpha" "beta" "gamma" 
R> 
+0

Cảm ơn bạn đã trả lời bằng ví dụ. Vì vậy, nó có nghĩa là luôn luôn thuận tiện để sử dụng 'colnames()' thay vì 'names()'? Có tình huống tương tự cho tên hàng không? –

+2

Có sự khác biệt giữa các loại dữ liệu. – Jay

+5

Emerson nói: "Một sự thống nhất ngu xuẩn là hobgoblin của tâm trí nhỏ bé, được yêu mến bởi các tiểu bang và triết gia và thần thánh nhỏ. Với tính nhất quán, một linh hồn vĩ đại đơn giản là không có gì để làm." –

8

Chỉ cần để mở rộng một chút về dụ Dirk của:

Nó giúp để nghĩ về một khung dữ liệu như một danh sách với chiều dài bằng nhau vectơ. Đó có thể là lý do tại sao names hoạt động với một khung dữ liệu nhưng không phải là ma trận.

Hàm hữu ích khác là dimnames trả về tên cho mọi thứ nguyên. Bạn sẽ nhận thấy rằng hàm rownames thực sự chỉ trả về phần tử đầu tiên từ dimnames.

Về rownamesrow.names: Tôi không thể nói sự khác biệt, mặc dù rownames sử dụng dimnames khi row.names được viết bên ngoài của R. Cả hai cũng có vẻ làm việc với mảng chiều cao:

>a <- array(1:5, 1:4) 
> a[1,,,] 
> rownames(a) <- "a" 
> row.names(a) 
[1] "a" 
> a 
, , 1, 1  
    [,1] [,2] 
a 1 2 

> dimnames(a) 
[[1]] 
[1] "a" 

[[2]] 
NULL 

[[3]] 
NULL 

[[4]] 
NULL 
+1

Đây là câu trả lời hay hơn. Snark rất vui, nhưng kiến ​​thức thì hữu ích hơn. 'data.frame' thực sự có thể sử dụng được dưới dạng danh sách các cột và ma trận, nghĩa là mỗi cột có cùng độ dài và bạn có thể trích xuất các hàng hoặc tập hợp con của các hàng. –

5

Tôi nghĩ rằng sử dụng colnamesrownames có ý nghĩa nhất; đây là lý do tại sao.

Sử dụng names có một số nhược điểm. Bạn phải nhớ rằng nó có nghĩa là "tên cột", và nó chỉ hoạt động với khung dữ liệu, vì vậy bạn sẽ cần phải gọi colnames bất cứ khi nào bạn sử dụng ma trận. Bằng cách gọi số colnames, bạn chỉ cần nhớ một chức năng. Cuối cùng, nếu bạn nhìn vào mã cho colnames, bạn sẽ thấy rằng nó gọi names trong trường hợp của khung dữ liệu, vì vậy đầu ra giống hệt nhau.

rownamesrow.names trả về cùng giá trị cho khung dữ liệu và ma trận; sự khác biệt duy nhất mà tôi đã phát hiện là ở chỗ không có bất kỳ tên nào, rownames sẽ in "NULL" (cũng như colnames), nhưng row.names trả về nó một cách vô hình. Vì không có nhiều lựa chọn giữa hai chức năng, nên rownames sẽ thắng vì lý do thẩm mỹ, vì nó đẹp hơn với colnames. (Ngoài ra, đối với lập trình viên lười biếng, bạn lưu một ký tự gõ.)

2

Và mở rộng khác:

# create dummy matrix 
set.seed(10) 
m <- matrix(round(runif(25, 1, 5)), 5) 
d <- as.data.frame(m) 

Nếu bạn muốn gán tên cột mới, bạn có thể làm sau trên data.frame:

# an identical effect can be achieved with colnames() 
names(d) <- LETTERS[1:5] 
> d 
    A B C D E 
1 3 2 4 3 4 
2 2 2 3 1 3 
3 3 2 1 2 4 
4 4 3 3 3 2 
5 1 3 2 4 3 

Nếu bạn, tuy nhiên chạy lệnh trước đó trên matrix, bạn' ll mess things up:

names(m) <- LETTERS[1:5] 
> m 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 3 2 4 3 4 
[2,] 2 2 3 1 3 
[3,] 3 2 1 2 4 
[4,] 4 3 3 3 2 
[5,] 1 3 2 4 3 
attr(,"names") 
[1] "A" "B" "C" "D" "E" NA NA NA NA NA NA NA NA NA NA NA NA NA NA 
[20] NA NA NA NA NA NA 

Vì ma trận có thể b e coi là vector hai chiều, bạn sẽ chỉ gán tên cho năm giá trị đầu tiên (bạn không muốn làm điều đó, phải không?). Trong trường hợp này, bạn nên gắn bó với colnames().

Vì vậy, có ...

Các vấn đề liên quan