每行计算满足条件的实例数量 R

7

我有一个大文件,第一列是ID,其余的1304列是像下面这样的基因型。

rsID    sample1    sample2    sample3...sample1304
abcd    aa         bb         nc        nc
efgh    nc         nc         nc        nc 
ijkl    aa         ab         aa        nc 

我希望能够对每行中 "nc" 值的数量进行计数,并将结果输出到另一列中,从而得到以下结果:
rsID    sample1    sample2    sample3...sample1304    no_calls
abcd    aa         bb         nc        nc            2
efgh    nc         nc         nc        nc            4
ijkl    aa         ab         aa        nc            1

表格函数按列计算频率,而不是行。如果我要转置数据以在表格函数中使用,我需要将文件看起来像这样:
abcd         aa[sample1]
abcd         bb[sample2]
abcd         nc[sample3] ...
abcd         nc[sample1304]
efgh         nc[sample1]
efgh         nc[sample2]
efgh         nc[sample3] ...
efgh         nc[sample1304]

使用这种格式,我可以得到以下输出结果,这正是我想要的:
ID    nc   aa   ab   bb
abcd  2    1    0    1
efgh  4    0    0    0

有没有简单的方法可以按行获取频率?我现在正在尝试这个方法,但运行起来需要很长时间:

rsids$Number_of_no_calls <- apply(rsids, 1, function(x) sum(x=="NC"))

R 是区分大小写的。数据显示“nc”,但应用程序中使用的是“NC”...¿? - PereG
rowSums 可能是正确的函数。 - talat
1个回答

17

你可以使用rowSums

df$no_calls <- rowSums(df == "nc")
df
#  rsID sample1 sample2 sample3 sample1304 no_calls
#1 abcd      aa      bb      nc         nc        2
#2 efgh      nc      nc      nc         nc        4
#3 ijkl      aa      ab      aa         nc        1

正如MrFlick所指出的那样,为了从行总和中排除第一列,您可以稍微修改方法:

df$no_calls <- rowSums(df[-1] == "nc")

关于行名称:它们在 rowSums 中不被计算,你可以进行一个简单的测试来证明:

rownames(df)[1] <- "nc"  # name first row "nc"
rowSums(df == "nc")      # compute the row sums
#nc  2  3             
# 2  4  1        # still the same in first row

1
也许可以使用 df$no_calls <- rowSums(df[,-1] == "nc") 来忽略第一列中的任何 "nc" 值。 - MrFlick
@MrFlick,如果该列中有任何要点,那就是个好观点。 - talat
@doc 如果将第一列读入为行名,那么您发布的原始代码是否会计算第一列中的“nc”值? - nchimato
@nchimato,不,它不会。 - talat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接