【问题标题】:taking the sum of a TRUE/FALSE vector in r在 r 中取真/假向量的总和
【发布时间】:2015-09-21 05:45:27
【问题描述】:

我正在分析一种真菌的 SNP 数据,我试图通过将 Ns 更改为更频繁的等位基因的基因型来估算缺失的数据......见下文。 newdata 是我的 snps(行)和真菌分离物(列)的矩阵。每个 snp 的基因型都采用 0、1 和 N 格式,这就是我试图估算缺失的基因型的原因。

newdata_imputed=newdata
for (k in 1:nrow(newdata)){
u=newdata[k,]
x<-sum(u==0)
y<-sum(u==1)
all_freq=y/(x+y)
if (all_freq<0.5){
newdata_imputed[k,]=gsub("N",0,u)
} else{newdata_imputed[k,]=gsub("N",1,u)}
print(k)
}

但是,我不断收到此错误:

[1] 295
[1] 296
Error in if (all_freq < 0.5) { : missing value where TRUE/FALSE needed

很明显,代码运行但遇到问题后停止。请,有人可以告诉我我做错了什么吗?我是 R 的新手,任何建议都将不胜感激。

@akrun,我使用 for 循环的原因是因为它嵌套在另一个 for 循环中......所以在使用您的代码之后。

newdata=as.data.frame(newdata)
u=newdata
all_freq <- rowSums(u==1)/rowSums((u==1)|(u==0))
indx <- all_freq < 0.5
indx1 <-  indx & !is.na(indx)
indx2 <- !indx & !is.na(indx)
newdata[indx1,] <- lapply(newdata[indx1,], gsub, pattern='N', replacement=0)
newdata[indx2,] <- lapply(newdata[indx2,], gsub, pattern='N', replacement=1)
newdata[] <- lapply(newdata, as.numeric)

我得到了奇怪的值

newdata[1:10,1:10]
   V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
1   3  3  3  3  3  3  3  3  3   3
2   2  2  2  2  2  2  2  2  2   2
3   3  3  3  3  3  3  3  3  3   3
4   1  1  1  1  1  1  1  1  1   1

请问“3”是从哪里来的????我应该只有 0 或 1

【问题讨论】:

  • 看起来您有一行缺少 01 值。
  • 我认为如果您粘贴一些数据以使您的代码可重现,这将大有帮助。
  • 看起来粘贴第 297 行可能最有帮助。
  • 您可能不需要for 循环。您可以使用 all_freq &lt;- rowMeans(newdata==1); i1 &lt;- all_freq&lt;0.5 并使用该索引来替换行值。
  • 我猜x + y == 0。然后all_freq == NaN(all_freq&lt;0.5) == NA。如果与NA 一起使用,if 会报告此错误。

标签: r


【解决方案1】:

我们可以使用rowSums 做到这一点。正如@bergant 和@MatthewLundberg 在 cmets 中提到的,如果有没有 0 或 1 个元素的行,我们会根据计算得到 NaN。一种方法是通过包含!is.na 来修改逻辑条件,即不是NA 的元素与先前的条件一起。

#using `rowSums` to create the all_freq vector 
all_freq <- rowSums(newdata==1)/rowSums((newdata==1)|(newdata==0))
#Create a logical index based on elements that are less than 0.5
indx <- all_freq < 0.5 
#The NA elements can be changed to FALSE by adding another condition
indx1 <-  indx & !is.na(indx)
#similarly for elements that are > 0.5 
indx2 <- !indx & !is.na(indx)

现在,我们使用 'indx1' 对 'newdata' 的行进行子集化,遍历列 (lapply) 并将 gsubpatternreplacement 参数一起使用,并将输出分配回子集的“新数据”。

newdata[indx1,] <- lapply(newdata[indx1,], gsub, pattern='N', replacement=0)

同样,我们可以对大于 0.5 的行进行 'all_freq' 的替换

newdata[indx2,] <- lapply(newdata[indx2,], gsub, pattern='N', replacement=1)

gsub 输出列是character 类,可以转换回numeric(如果需要)。

newdata[] <- lapply(newdata, as.numeric)

数据

set.seed(24)
newdata <- as.data.frame(matrix(sample(c(0:1, "N"), 10*4, replace=TRUE),
         ncol=4), stringsAsFactors=FALSE)
newdata[7,] <- 2

【讨论】:

  • 好的,您的代码可以正常运行。但我得到了奇怪的数字......我应该得到 0 和 1,但我得到 2 和 3。我在调整代码时做错了什么?
  • @Nolage86 请使用小示例数据和基于此的预期输出更新您的帖子。我会使用dput 来展示这个例子。即dput(droplevels(newdata[1:5, 1:5])))
  • @akrun .....经过一番努力,我终于找到了错误的根源。你的代码很有帮助。多谢! :-)
  • @akrun..........谢谢你提醒我点击勾选标记。我绝对是这里的新手:-)。首先,我必须完全重新编码我的数据。然后,我不得不删除单态标记(行)。如果我有所有分类群(列)的基因型相同的标记,则该代码将不起作用。再次谢谢你。像你这样的编码大师对于像我这样的新手来说是一个真正的祝福。 :-)
猜你喜欢
  • 1970-01-01
  • 2014-08-02
  • 1970-01-01
  • 1970-01-01
  • 2020-09-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
相关资源
最近更新 更多