我正在尝试将各种列添加到一起,rowSums但我遇到了一些问题。以下是列名列表:
colnames(No_Low_No_Intergenic_snpeff)
"CHROM" "POS" "REF" "ALT" "QUAL" "ANN.ALLELE" "ANN.EFFECT"
"ANN.IMPACT" "ANN.GENE" "ANN.GENEID" "ANN.FEATURE" "ANN.FEATUREID"
"ANN.HGVS_C" "ANN.HGVS_P" "ANN.ERRORS" "GEN.C02141.GT" "GEN.C00611.GT"
"GEN.C00633.GT" "GEN.C00634.GT" "GEN.C00644.GT" "GEN.C00647.GT" "GEN.C00648.GT"
"GEN.C00649.GT" "GEN.C00650.GT" "GEN.C00653.GT" "GEN.C00655.GT" "GEN.C00656.GT"
"GEN.C00657.GT" "GEN.C00659.GT" "GEN.C00682.GT" "GEN.C00705.GT" "GEN.C00707.GT"
"GEN.C00720.GT" "GEN.C00783.GT" "GEN.C01431.GT" "GEN.C01944.GT" "GEN.C01943.GT"
"GEN.C01403.GT" "GEN.C01158.GT" "GEN.C01157.GT" "GEN.C01156.GT" "GEN.C01033.GT"
"GEN.C00736.GT" "GEN.C00639.GT" "GEN.C99686.GT"
Run Code Online (Sandbox Code Playgroud)
我正在使用的GEN.Cxxxxx.GT所有列都带有标签,并且这些列中的所有值范围为 0-2。我试图对第 20:29 列和第 45 列求和,然后将这些值放在一个名为 的新列中controls:
No_Low_No_Intergenic_snpeff.scores$controls <- rowSums(No_Low_No_Intergenic_snpeff.scores[,20:29,45])
Run Code Online (Sandbox Code Playgroud)
但是当我尝试运行该命令时,出现以下错误:
Error in rowSums(No_Low_No_Intergenic_snpeff.scores[, 20:29, 45]) : 'x' must be numeric
Run Code Online (Sandbox Code Playgroud)
数据
str(No_Low_No_Intergenic_snpeff.scores)
'data.frame': 1000 obs. of 11 variables:
$ GEN.C00644.GT: Factor w/ 3 levels "0","1","2": 3 1 1 3 3 3 2 1 3 1 ...
$ GEN.C00647.GT: Factor w/ 3 levels "0","1","2": 3 1 3 3 2 2 2 1 2 1 ...
$ GEN.C00648.GT: Factor w/ 3 levels "0","1","2": 3 1 1 3 3 3 1 1 2 1 ...
$ GEN.C00649.GT: Factor w/ 3 levels "0","1","2": 3 1 1 3 2 2 2 1 2 1 ...
...
Run Code Online (Sandbox Code Playgroud)
您收到此错误是因为值不是numeric。看看你的输出str:
GEN.C00650.GT: Factor w/ 3 levels "0","1","2": 3 1 3 3 3 3 1 1 3 1 ...
Run Code Online (Sandbox Code Playgroud)
这些是类factor,而不是类numeric。要将它们作为数字处理,您需要使用以下方法将它们转换为数字as.numeric
如果您可以再次从文件中导入数据,则可以使用stringsAsFactors = FALSE参数执行此操作。您几乎应该总是使用这个参数,因为没有它,所有字符串(以及大多数数字,如您在此处看到的)都将转换为因子,从而产生各种烦人的问题,直到您将它们改回来。
从R 4.0.0 开始,这不再是必需的,因为 的默认值stringsAsFactors已更改为FALSE。这有望使这个常见的错误成为过去
最简单的方法是使用sapply:
rowSums(sapply(No_Low_No_Intergenic_snpeff.scores[, c(20:29, 45)],
function(x) as.numeric(as.character(x))))
Run Code Online (Sandbox Code Playgroud)
这将您的 data.frame 子集化,将as.numeric函数应用于每一行,然后计算rowSums。
您还可以使用mutate_iffrom 函数dplyr将所有因子变量转换为数值。
library(dplyr)
No_Low_No_Intergenic_snpeff.scores <- No_Low_No_Intergenic_snpeff.scores %>%
mutate_if(is.factor, ~as.numeric(as.character(.)))
rowSums(No_Low_No_Intergenic_snpeff.scores[, c(20:29, 45)])
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用mutate_at按位置或名称选择列。阅读?select以了解您可以选择列的所有不同方式。您甚至可以使用带有 的正则表达式matches,如下所示:
No_Low_No_Intergenic_snpeff.scores <- No_Low_No_Intergenic_snpeff.scores %>%
mutate_at(vars(matches('GEN.C\\d{5}.GT')), funs(as.numeric))
Run Code Online (Sandbox Code Playgroud)
这将函数应用于as.numeric名称与正则表达式匹配的所有列GEN.C\\d{5}.GT,其中\\d{5}表示 5 个数字。