2013-07-09 29 views
16

Tôi đang sử dụng mã số colSums nhưng tôi cũng cần độ lệch chuẩn bên cạnh tổng. tôi đã tìm kiếm trên Internet và tìm thấy trang này mà chỉ chứa:Có "colsd" trong R không?

colSums 
colMeans 

http://stat.ethz.ch/R-manual/R-devel/library/base/html/colSums.html

Tôi cố gắng này:

colSd 

nhưng tôi đã nhận lỗi này:

Error: could not find function "colSd" 

Làm thế nào tôi có thể làm điều tương tự nhưng với độ lệch chuẩn:

colSd 

Đây là mã:

results <- colSums(x,na.rm=TRUE)#### here I want colsd 
+3

Không, nhưng nếu bạn có một data.frame, hãy thử 'sapply (x, sd) 'hoặc tổng quát hơn,' áp dụng (x, 2, sd) '. –

+0

https://stat.ethz.ch/pipermail/r-help/2002-March/019606.html –

+1

Tôi cũng thích hàm 'numcolwise' từ gói' plyr' cho loại điều này. – Justin

Trả lời

20

Tôi muốn cung cấp một cách tiếp cận thứ tư (rất giống với @Thomas) và một số điểm chuẩn:

library("microbenchmark") 
library("matrixStats") 

colSdApply <- function(x, ...)apply(X=x, MARGIN=2, FUN=sd, ...) 
colSdMatrixStats <- colSds 

colSdColMeans <- function(x, na.rm=TRUE) { 
    if (na.rm) { 
    n <- colSums(!is.na(x)) # thanks @flodel 
    } else { 
    n <- nrow(x) 
    } 
    colVar <- colMeans(x*x, na.rm=na.rm) - (colMeans(x, na.rm=na.rm))^2 
    return(sqrt(colVar * n/(n-1))) 
} 

colSdThomas <- function(x)sqrt(rowMeans((t(x)-colMeans(x))^2)*((dim(x)[1])/(dim(x)[1]-1))) 

m <- matrix(runif(1e7), nrow=1e3) 

microbenchmark(colSdApply(m), colSdMatrixStats(m), colSdColMeans(m), colSdThomas(m)) 

# Unit: milliseconds 
#     expr  min  lq median  uq  max neval 
#  colSdApply(m) 435.7346 448.8673 456.6176 476.8373 512.9783 100 
# colSdMatrixStats(m) 344.6416 357.5439 383.8736 389.0258 465.5715 100 
#  colSdColMeans(m) 124.2028 128.9016 132.9446 137.6254 172.6407 100 
#  colSdThomas(m) 231.5567 240.3824 245.4072 274.6611 307.3806 100 


all.equal(colSdApply(m), colSdMatrixStats(m)) 
# [1] TRUE 
all.equal(colSdApply(m), colSdColMeans(m)) 
# [1] TRUE 
all.equal(colSdApply(m), colSdThomas(m)) 
# [1] TRUE 
+1

@sacvf: Tôi đã bỏ lỡ '...' trong 'colMeans' (xem phần chỉnh sửa của tôi). Bây giờ 'colSdColMeans (x, na.rm = TRUE)' sẽ hoạt động. – sgibb

+2

Tôi nghĩ rằng để đối phó với 'NA' bạn sẽ phải sử dụng một cái gì đó như' n <- colSums (! Is.na (x)) '. – flodel

+0

+1 cho điểm chuẩn của các phương pháp khác nhau. Điều này hữu ích và mới mẻ đối với tôi. – asb

4

Sử dụng như sau:

colSd <- function (x, na.rm=FALSE) apply(X=x, MARGIN=2, FUN=sd, na.rm=na.rm) 
+0

Tôi sẽ làm 'hàm (x, ...) áp dụng (X = x, ...)) '. –

+0

Tôi tranh luận rằng bản thân mình, nhưng sau đó sd chỉ sử dụng một tùy chọn, vì vậy tôi nghĩ đến việc bao gồm trực tiếp. – asb

+6

@sacvf, không quan trọng bạn nhận được bao nhiêu nhận xét với "kết quả của tôi là NA, bất kỳ ý tưởng nào tại sao?", Chúng tôi không thể giúp trừ khi chúng tôi thấy dữ liệu bạn gặp sự cố. Bạn nên chỉ đạo một số năng lượng của bạn để làm cho câu hỏi của bạn có thể tái sản xuất được. – Arun

4

colSdsrowSds là hai trong số nhiều chức năng tương tự trong matrixStats package

+4

Những chức năng trong gói đó không thực sự làm bất cứ điều gì ưa thích; chúng cũng chậm như 'áp dụng (x, 2, sd)'. – nograpes

4

tôi không biết nếu những điều này đặc biệt nhanh, nhưng tại sao không chỉ sử dụng các công thức cho SD:

x <- data.frame(y = rnorm(1000,0,1), z = rnorm(1000,2,3)) 

# If you have a population: 
colsdpop <- function(x,...) 
    sqrt(rowMeans((t(x)-colMeans(x,...))^2,...)) 
colsdpop(x) 
sd(x$y); sd(x$z) # won't match `sd` 

# If you have a sample: 
colsdsamp <- function(x) 
    sqrt((rowMeans((t(x)-colMeans(x))^2)*((dim(x)[1])/(dim(x)[1]-1)))) 
colsdsamp(x) 
sd(x$y); sd(x$z) # will match `sd` 

Lưu ý: giải pháp mẫu sẽ không xử lý tốt nhất NA s. Người ta có thể kết hợp một cái gì đó như apply(x,2,function(z) sum(!is.na(z))) vào phần bên phải của công thức để có được một mẫu số thích hợp, nhưng nó sẽ thực sự rất u ám.

1

Tôi tin rằng tôi đã tìm thấy một giải pháp thanh lịch hơn trong diag(sqrt(var(data)))

này làm việc cho tôi để có được độ lệch chuẩn của mỗi cột của tôi. Tuy nhiên, nó tính toán một loạt các hiệp phương sai không cần thiết (và rễ vuông của chúng) trên đường đi, vì vậy nó không nhất thiết là cách tiếp cận hiệu quả nhất. Nhưng nếu dữ liệu của bạn nhỏ, nó hoạt động xuất sắc.

EDIT: Tôi vừa nhận ra rằng sqrt(diag(var(data))) có lẽ hiệu quả hơn một chút, vì nó giảm các thuật ngữ hiệp phương sai không cần thiết trước đó.

0

Đây là cách nhanh nhất và ngắn nhất để tính toán độ lệch chuẩn của các cột:

sqrt(diag(cov(data_matrix))) 

Kể từ khi đường chéo của một đồng đúng ma trận bao gồm các phương sai của mỗi biến, chúng ta thực hiện như sau:

  • Tính ma trận đồng phương sai sử dụng cov
  • Giải nén đường chéo của ma trận sử dụng diag
  • Lấy căn bậc hai của các giá trị sử dụng đường chéo sqrt để có được độ lệch chuẩn

Tôi hy vọng rằng sẽ giúp :)

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