Ошибка в colMeans(x, na.rm = TRUE): ‘x’ должен быть числовым

#r #cluster-analysis

#r #кластерный анализ

Вопрос:

Я пытаюсь провести кластерный анализ, который требует от меня масштабирования / стандартизации моих данных. Данные находятся в матрице и являются числовыми, однако я получаю только следующее сообщение:

 Error in colMeans(x, na.rm = TRUE) : 'x' must be numeric
  

Изначально был столбец, содержащий категориальные данные, поэтому я удалил его, думая, что это решит проблему, но я все равно получил ошибку.

Ниже приведены фрагменты сценария и 6 строк данных. Любая помощь была бы высоко оценена.

 Metals <- as.matrix(d)
rownames(Metals)<-d$RowLabs
cols_to_keep <-c(FALSE,TRUE,TRUE,TRUE,TRUE,TRUE) 
Metals<-Metals[,cols_to_keep]
head(Metals)
  
     X88Sr_umol_molCa X25Mg_umol_molCa X55Mn_umol_molCa X7Li_umol_molCa
CHR1 "1748.3722"      "    80.284613"  " 1.353754e-01"  "   3.2146056" 
CLR2 "1763.6984"      "   104.850260"  " 4.944963e-01"  "   0.2649073" 
CLR3 "2245.8861"      "   186.579911"  " 2.124642e-01"  "   1.0715352" 
CLR4 "1654.9811"      "   124.502777"  " 4.756491e-01"  "   0.2252010" 
CLR5 "1447.3079"      "   183.703436"  " 4.734605e-01"  "   2.8409970" 
CLR6 "1731.3718"      "   170.511088"  " 1.728970e-01"  "   2.5984728" 
     X138Ba_umol_molCa
CHR1 " 1.3426978"     
CLR2 "10.3955650"     
CLR3 "12.8552971"     
CLR4 "12.3339241"     
CLR5 " 0.9453284"     
CLR6 " 2.1714244" 
  
 d <- scale(Metals)
head(Metals)
  

Ошибка в colMeans(x, na.rm = TRUE): ‘x’ должен быть числовым

Комментарии:

1. Привет, Анжела! Из 6 строк данных, которые вы предоставляете, похоже, что ваши числа интерпретируются как символы R (потому что они заключены в кавычки — «»). Возможно, именно поэтому появляется ошибка. Вы можете преобразовать эти числа, применив функцию as.double().

2. Кроме того. В следующий раз, когда вы обратитесь за помощью, пожалуйста, используйте функцию dput() для вашего объекта «d», чтобы обеспечить надлежащий способ воспроизведения ваших данных. 6 строк данных, которые вы предоставляете, не очень помогают нам решить вашу проблему.

3. Спасибо за вашу помощь, Педро. Я не уверен, почему они в кавычках. Как мне их удалить?

4. Я просто редактирую прошлый комментарий. Вы можете использовать функцию as.double() для вашего объекта «d», которая, вероятно, работает.

5. Спасибо, что также сообщили мне о функции dput(). Как именно это будет выглядеть? Не могли бы вы, пожалуйста, показать мне код, который я предоставил?

Ответ №1:

Ваши данные кажутся символами. Что class(Metals) возвращает?

Преобразуйте данные в числовые, а затем попробуйте scale функцию :

 Metals[] <- as.numeric(Metals)
d <- scale(Metals)
  

Ответ №2:

Таблица неправильно прочитана, вы можете видеть, что, например, в столбце «X25Mg_umol_molCa» ваши записи являются строками и имеют начальный пробел, например, «80.284613».

Скорее всего, в вашем файле есть некоторые записи, из-за которых он читается именно так, а не в виде числового столбца. Я думаю, что первое, что вы должны попытаться сделать, это использовать, например:

 df = read.table(<file>,header=TRUE,sep="t")
str(df)
  

И посмотрите, являются ли столбцы теперь числовыми.

С вашими текущими несколькими строками мы можем что-то сделать, чтобы удалить пробелы, надеюсь, это решит проблему:

 df = structure(c("1748.3722", "1763.6984", "2245.8861", "1654.9811", 
"1447.3079", "1731.3718", "    80.284613", "    104.85026", "   186.579911", 
"   124.502777", "   183.703436", "   170.511088", " 1.353754e-01", 
" 4.944963e-01", " 2.124642e-01", " 4.756491e-01", " 4.734605e-01", 
" 1.728970e-01", "   3.2146056", "   0.2649073", "   1.0715352", 
"   0.2252010", "   2.8409970", "   2.5984728", " 1.3426978", 
"10.3955650", "12.8552971", "12.3339241", " 0.9453284", " 2.1714244"
), .Dim = 6:5, .Dimnames = list(NULL, c("X88Sr_umol_molCa", "X25Mg_umol_molCa", 
"X55Mn_umol_molCa", "X7Li_umol_molCa", "X138Ba_umol_molCa")))

 df
     X88Sr_umol_molCa X25Mg_umol_molCa X55Mn_umol_molCa X7Li_umol_molCa
[1,] "1748.3722"      "    80.284613"  " 1.353754e-01"  "   3.2146056" 
[2,] "1763.6984"      "    104.85026"  " 4.944963e-01"  "   0.2649073" 
[3,] "2245.8861"      "   186.579911"  " 2.124642e-01"  "   1.0715352" 
[4,] "1654.9811"      "   124.502777"  " 4.756491e-01"  "   0.2252010" 
[5,] "1447.3079"      "   183.703436"  " 4.734605e-01"  "   2.8409970" 
[6,] "1731.3718"      "   170.511088"  " 1.728970e-01"  "   2.5984728" 
     X138Ba_umol_molCa
[1,] " 1.3426978"     
[2,] "10.3955650"     
[3,] "12.8552971"     
[4,] "12.3339241"     
[5,] " 0.9453284"     
[6,] " 2.1714244"

df = apply(gsub(" ","",df),2,as.numeric)
scale(df)

     X88Sr_umol_molCa X25Mg_umol_molCa X55Mn_umol_molCa X7Li_umol_molCa
[1,]     -0.064262779       -1.3718203       -1.1268227       1.1249317
[2,]     -0.005975399       -0.8234489        0.9806457      -1.0696716
[3,]      1.827842350        1.0009771       -0.6744341      -0.4695329
[4,]     -0.419440351       -0.3847518        0.8700426      -1.0992135
[5,]     -1.209246479        0.9367664        0.8571990       0.8469633
[6,]     -0.128917342        0.6422776       -0.9066306       0.6665231
     X138Ba_umol_molCa
[1,]        -0.9263654
[2,]         0.6466464
[3,]         1.0740455
[4,]         0.9834525
[5,]        -0.9954117
[6,]        -0.7823672
attr(,"scaled:center")
 X88Sr_umol_molCa  X25Mg_umol_molCa  X55Mn_umol_molCa   X7Li_umol_molCa 
     1765.2695833       141.7386808         0.3273904         1.7026198 
X138Ba_umol_molCa 
        6.6740395 
attr(,"scaled:scale")
 X88Sr_umol_molCa  X25Mg_umol_molCa  X55Mn_umol_molCa   X7Li_umol_molCa 
      262.9419965        44.7974607         0.1704039         1.3440690 
X138Ba_umol_molCa 
        5.7551172 
  

Ответ №3:

Матрицы в R представляют собой векторы с 2 измерениями, поэтому, применяя непосредственно функцию as.double(), вы сможете преобразовать свои данные, находящиеся внутри вашей матрицы, в числовые значения.

 d <- as.double(d)
  

Посмотрим, сработает ли это.

Комментарии:

1. возвращенный класс (металлы): [1] «матрица», «массив»

2. Это изменение в исходном сценарии решило проблему: Металлы <- as.matrix(d[,-1]) имена строк(Металлы)<-d$RowLabs head(металлы)