Есть ли такой "colsd" в R?

Я использую в своем коде colSums, но мне также нужно стандартное отклонение помимо суммы. Я искал в интернете и нашел эту страницу, которая содержит только:

colSums
colMeans

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

Я попробовал это:

colSd

но я получил эту ошибку:

Error: could not find function "colSd"

Как я могу сделать то же самое, но для стандартного отклонения:

colSd

Вот код:

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

Ответы

Ответ 1

Я хочу предоставить четвертый подход (очень похожий на @Thomas) и некоторый бенчмаркинг:

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

Ответ 2

colSds и rowSds - две из многих похожих функций в пакете matrixDats .

Ответ 3

Используйте следующее:

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

Ответ 4

Я не знаю, если это особенно быстро, но почему бы просто не использовать формулы для 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`

Примечание: образец решения не будет обрабатывать NA. Можно было бы включить что-то вроде apply(x,2,function(z) sum(!is.na(z))) в правую часть формулы, чтобы получить соответствующий знаменатель, но он будет очень мутным довольно быстро.

Ответ 5

Я считаю, что нашел более элегантное решение в diag(sqrt(var(data)))

Это помогло мне получить стандартное отклонение от каждого из моих столбцов. Тем не менее, он вычисляет кучу лишних ненужных ковариаций (и их квадратных корней) на этом пути, поэтому это не обязательно самый эффективный подход. Но если ваши данные малы, он отлично работает.

EDIT: я только понял, что sqrt(diag(var(data))), вероятно, немного эффективнее, так как раньше он освобождает ненужные условия ковариации.

Ответ 6

Это самый быстрый и самый короткий способ вычисления стандартного отклонения столбцов:

sqrt(diag(cov(data_matrix)))

Так как диагональ матрицы совпадений состоит из дисперсий каждой переменной, мы делаем следующее:

  • Вычислите матрицу совместного дисперсии с помощью cov
  • Извлечь диагональ матрицы с помощью diag
  • Возьмите квадратный корень из диагональных значений, используя sqrt, чтобы получить стандартное отклонение

Надеюсь, что это поможет:)

Ответ 7

Я обычно делаю столбец SD с apply:

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

> apply(x, 2, sd)
        y         z 
0.8022729 3.4700314 

Проверка:

> sd(x$y)
[1] 0.8022729

> sd(x$z)
[1] 3.470031

Вы также можете легко сделать это с помощью dplyr:

library(dplyr)
library(magrittr) # for pipes

> x %>% summarize_all(.,sd)
          y        z
1 0.8022729 3.470031