2010-06-18 33 views
24

Tôi muốn thêm một biến (cột) vào một khung dữ liệu (df), chứa trong mỗi hàng giá trị lớn nhất của hàng đó trên cột thứ 2 đến thứ 26.Thêm biến vào khung dữ liệu chứa giá trị lớn nhất của mỗi hàng

Đối với hàng đầu tiên, mã sẽ là:

df$max[1] <- max(df[1,2:26]) 

Tôi đang tìm kiếm một cách khái quát rằng cho các hàng từ 1 tới 865. Nếu tôi đưa ra:

df$max[1:865] <- max(df[1:865, 2:26]) 

tôi nhận được tổng số tối đa trên tất cả các hàng cho biến số df$max.

Trả lời

29

Bạn có thể sử dụng apply. Ví dụ:

df[, "max"] <- apply(df[, 2:26], 1, max) 

Dưới đây là một ví dụ cơ bản:

> df <- data.frame(a=1:50, b=rnorm(50), c=rpois(50, 10)) 
> df$max <- apply(df, 1, max) 
> head(df, 2) 
    a   b c max 
1 1 1.3527115 9 9 
2 2 -0.6469987 20 20 
> tail(df, 2) 
    a   b c max 
49 49 -1.4796887 10 49 
50 50 0.1600679 13 50 
+1

gì nếu tôi muốn tên của cột trong max cho mỗi hàng .. ví dụ df $ max [1] = c – syllogismos

+1

nếu tôi cần thêm na.rm = TRUE thì sao? – KillerSnail

23

phiên bản vector hóa với pmax:

df$max <- do.call(pmax, df[2:26]) 
+1

+1 Quên về chức năng pmax. – Shane

+0

Cảm ơn rất nhiều vì điều này. –

0

Một phương pháp vô cùng nhanh là kết hợp ma trận chiết [ với max.col, mà trả về một vector lập chỉ mục vị trí cột của giá trị tối đa trong mỗi hàng.

df$max <- df[2:26][cbind(seq_len(nrow(df)), max.col(df[2:26]))] 

cbind xây dựng một ma trận lập chỉ mục vị trí của các giá trị tối đa cho mỗi hàng và [ sử dụng này để trích xuất giá trị này.


Hãy làm một số điểm chuẩn.

# data.frame with 1000 observations and 26 variables 
set.seed(1234) 
df <- data.frame(id=paste0(letters[-1], 1:40), matrix(rnorm(25000L, 5L, 10L), 1000L)) 

Đồng thời thêm chức năng rowMaxs từ gói matrixStats vào danh sách kết hợp.

library(matrixStats) 
library(microbenchmark) 

microbenchmark(apply=apply(df[, 2:26], 1, max), 
       pmax=do.call(pmax, df[2:26]), 
       max.colSub=df[2:26][cbind(seq_len(nrow(df)), max.col(df[2:26]))], 
       rowMaxs=rowMaxs(as.matrix(df[2:26]))) 
Unit: microseconds 
     expr  min  lq  mean median  uq  max neval cld 
     apply 1610.540 1786.5905 2193.5334 1863.5680 1990.4380 6915.999 100 c 
     pmax 354.382 364.6455 380.1720 373.3405 385.4580 567.923 100 a 
    max.colSub 604.416 651.7430 822.6015 664.7155 681.2510 3086.512 100 b 
    rowMaxs 243.762 264.0040 320.2350 277.9750 290.5190 2328.712 100 a 

Vì vậy, rowMaxs là người chiến thắng rõ ràng tiếp theo pmax và sau đó bởi max.col, với chiết xuất ma trận, và apply vào cuối đuôi của gói.

Với một data.frame với 10000 hàng và 26 cột, chúng tôi nhận được một câu chuyện tương tự:

set.seed(1234) 
df <- data.frame(id=paste0(letters[-1], 1:400), matrix(rnorm(250000L, 5L, 10L), 10000L)) 

Đoạn mã trên trả về

Unit: milliseconds 
     expr  min  lq  mean median  uq  max neval cld 
     apply 15.193361 18.299830 21.737516 20.337880 21.774793 99.44836 100 c 
     pmax 3.060853 3.101481 3.156630 3.137545 3.191430 3.54182 100 a 
max.colSub 3.338828 3.642603 7.051700 3.992708 6.336531 84.43119 100 b 
    rowMaxs 1.244184 1.322302 2.675281 1.508474 1.638053 79.28054 100 a 
Các vấn đề liên quan