У меня есть следующая матрица - example:

        col1      col2      col3
S01LA   "0.0143"  "0.1286"  "---"                          
N01AX "0.0088"    "---"     "0.343"                         
N05AG "0.0927"    "0.8692"  "---"                             

И я хочу получить среднее значение каждой строки. Я попытался сделать это, изменив значения "---" на NA, а затем используя colSums

example[example=='---'] <- NA
row_means <- rowMeans(as.numeric(example), na.rm=TRUE)

Что дает мне ошибку

Error in colSums(as.numeric(copy_specificity_df), na.rm = TRUE) : 
   'x' must be an array of at least two dimensions 

Поскольку as.numeric выравнивает фрейм данных. Как я могу получить среднее значение всех строк в кадре данных, игнорируя элементы, которые нельзя преобразовать в числа с плавающей запятой?

-3
Niek de Klein 9 Май 2014 в 21:21

3 ответа

Лучший ответ

Отображение вашего "примера" объекта и предпринятые вами попытки указывают мне, что даже если вы называете свой объект data.frame, на самом деле это matrix.

Я намекаю, что вы действительно используете matrix?

  1. data.frame обычно не печатают кавычки вокруг строк.
  2. as.numeric(some_data_frame) выдаст вам ошибку о принуждении list к удвоению.

При этом вот несколько примеров данных:

example <- structure(c("0.0143", "0.0088", "0.0927", "0.1286", 
                 "---", "0.8692", "---", "0.343", "---"), 
               .Dim = c(3L, 3L), 
               .Dimnames = list(c("S01LA", "N01AX", "N05AG"), 
                                c("col1", "col2", "col3")))
example
#       col1     col2     col3   
# S01LA "0.0143" "0.1286" "---"  
# N01AX "0.0088" "---"    "0.343"
# N05AG "0.0927" "0.8692" "---"  

Вот подход, который вы можете использовать в этом случае.

example[example == "---"] <- NA   ## Replace "---" with `NA`
N <- as.numeric(example)          ## Convert to numeric. You can start here
dim(N) <- dim(example)            ## Restore the dimensions
dimnames(N) <- dimnames(example)  ## Restore the dimnames
colMeans(N, na.rm=TRUE)           ## Perform your calculation
#   col1   col2   col3 
# 0.0386 0.4989 0.3430 

Примечание. На самом деле вы можете пропустить первую строку, но получите warning.

1
A5C1D2H2I1M1N2O1R2T1 9 Май 2014 в 17:48

Если вы заранее знаете, как выглядят значения NA в необработанных данных, вы можете использовать na.strings в read.table. Это эффективно считывает ваши данные как три числовых столбца. Подружитесь с args.

> dat <- read.table(text = 'col1      col2      col3
  S01LA   "0.0143"  "0.1286"  "---"                          
  N01AX "0.0088"    "---"     "0.343"                         
  N05AG "0.0927"    "0.8692"  "---"', na.strings = "---")
> dat
#         col1   col2  col3
# S01LA 0.0143 0.1286    NA
# N01AX 0.0088     NA 0.343
# N05AG 0.0927 0.8692    NA
> colSums(dat, na.rm = TRUE)
##   col1   col2   col3 
## 0.1158 0.9978 0.3430 
> rowMeans(dat, na.rm = TRUE)
##   S01LA   N01AX   N05AG 
## 0.07145 0.17590 0.48095
2
Rich Scriven 9 Май 2014 в 17:50

Вот один способ.

dat <- read.table(text = 'col1      col2      col3
S01LA   "0.0143"  "0.1286"  "---"                          
N01AX "0.0088"    "---"     "0.343"                         
N05AG "0.0927"    "0.8692"  "---"')

Сначала преобразуйте коэффициенты в числовые значения (предупреждающие сообщения можно игнорировать):

dat[] <- lapply(dat, function(x) if (is.factor(x)) as.numeric(as.character(x)) 
                                 else as.numeric(x))

#         col1   col2  col3
# S01LA 0.0143 0.1286    NA
# N01AX 0.0088     NA 0.343
# N05AG 0.0927 0.8692    NA

Во-вторых, примените colsums

colSums(dat, na.rm = TRUE)
#   col1   col2   col3 
# 0.1158 0.9978 0.3430 
1
Sven Hohenstein 9 Май 2014 в 18:18