R 求矩阵行的中位数和绝对偏差

R 求矩阵行的中位数和绝对偏差,r,matrix,R,Matrix,我有一个包含22239行和200列的数据框。第一列-名称-是字符,其他列是数字。我的目标是通过以下方式对行的所有元素进行操作: 找到行的中位数 从行元素(值)中减去中值 求行的中位数绝对偏差(mad) 将行元素除以行 我试过这样做 edata <- read.delim("a.txt", header=TRUE, sep="\t") ## Converting dataframe into Matrix ## Taking all rows but starting from 2 c

我有一个包含22239行和200列的数据框。第一列-
名称
-是字符,其他列是数字。我的目标是通过以下方式对行的所有元素进行操作:

  • 找到行的中位数
  • 从行元素(值)中减去中值
  • 求行的中位数绝对偏差(mad)
  • 将行元素除以行
我试过这样做

edata <- read.delim("a.txt", header=TRUE, sep="\t")

## Converting dataframe into Matrix
## Taking all rows but starting from 2 column to 200
data <- as.matrix(edata[,2:200]) 
for(i in 1:22239){  #rows below columns
    for(j in 1:200) {
        m <- median(data[i,]) # median of rows
        md <- mad(normdata[i,]) # mad of rows
        a <- data[i,j]  # assigning matrix element value to a
        subs = a-m    # substracting
        escore <- subs/md  # final score
        data[i,j] <- escore  # assigning final score to row elements

edataR与matlab一样,针对向量运算进行了优化。for循环可能是实现这一点最慢的方法。可以使用apply函数而不是for循环计算每行的中间值。这将为您提供中位数的列向量。e、 g

apply(edata,1,median)
类似的方法也可用于其他措施。请记住,在R/matlab中避免for循环通常会加快代码的速度。

这样做如何: (我创建了另一个矩阵作为起点,但方法相同)


dta您有处理行数据的特殊函数,但我喜欢使用apply。您可以将apply看作一个for循环(本质上是一次处理一行)

my.m <- matrix(runif(100), ncol = 5)
my.median <- apply(X = my.m, MARGIN = 1, FUN = median) #1
my.m - my.median #2
my.mad <- apply(X = my.m, MARGIN = 1, FUN = mad) #3
my.m/my.mad #4

my.m这是
sweep()
的理想工作

请注意,R的
mad()
乘以常数1.4826以获得渐近正态一致性,因此在第二个示例中增加了额外的位

我的系统上的一些计时:

## first version
   user  system elapsed 
  6.215   0.183   6.412 

## second version
   user  system elapsed 
  4.365   0.167   4.535 
对于@Nick的回答,我得到:

## @Nick's Version
   user  system elapsed 
  5.900   0.032   5.955

它始终比我的第一个版本快,但比第二个版本慢一点,这也是因为中位数计算了两次。

您可以将所有步骤放入函数中,只使用一个应用循环

rfun <- function(x) {
         me<- median(x)
         md<-mad(x,center=me,constant=1)
         return((x-me)/md)}

dat_s <- apply(dat,1,rfun)

rfun我建议您针对排序问题提出一个新问题。试着遵循这里发布的MRE指南:谢谢罗曼,这真的很有帮助,真的很棒。我会根据你的想法去理解suggestion@thchand这两个
sweep()
步骤与@Nick Sabbe的答案的最后一行相同,但方式类似于R。
## first version
   user  system elapsed 
  6.215   0.183   6.412 

## second version
   user  system elapsed 
  4.365   0.167   4.535 
## @Nick's Version
   user  system elapsed 
  5.900   0.032   5.955
rfun <- function(x) {
         me<- median(x)
         md<-mad(x,center=me,constant=1)
         return((x-me)/md)}

dat_s <- apply(dat,1,rfun)