5

我正在将 csv 文件读入 R 中,如下所示:

3,3
3,2
3,3
3,3
3,3
3,3
2,3
1,2
2,2
3,3

我想为我的数据可能的 9 种唯一可能性中的每一种分配一个数字(3 和 3 是 9,3 和 2 是 8,2 和 3 是 6,等等)。我一直在尝试设计一个嵌套的 if 语句,它将评估每一行,在第三列中分配一个数字,并对数据集中的每一行执行此操作。我相信这可以通过 apply 函数来完成,但是我无法让 if 语句在 apply 函数中工作。这两列都有可能的值 1,2 或 3。这是我到目前为止的代码,只是试图将 9 分配给 3/3 列,将 0 分配给其他所有内容:

#RScript for haplotype analysis

#remove(list=ls())
options(stringsAsFactors=FALSE)
setwd("C:/Documents and Settings/ColumbiaPC/Desktop")

#read in comma-delimited, ID-matched genotype data
OXT <- read.csv("OXTRhaplotype.csv")
colnames(OXT)<- c("OXT1","OXT2")

OXT$HAP <- apply(OXT, 1, function(x) if(x[1]=="3"&&x[2]=="3")x[3]=="9" else 0))

感谢您提前提供任何帮助。

4

4 回答 4

11

您可以使用矩阵和标准 R 子集来解决您描述的问题,而无需任何if陈述

m <- matrix(1:9, nrow=3, byrow=TRUE)
m

     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9

这意味着您可以使用矩阵子集对 m 进行索引:

m[3, 2]
[1] 8

m[3,3]
[1] 9

m[2,3]
[1] 6

现在您可以将其应用于您的数据:

df <- structure(list(V1 = c(3L, 3L, 3L, 3L, 3L, 3L, 2L, 1L, 2L, 3L), 
        V2 = c(3L, 2L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 3L)), .Names = c("V1", 
        "V2"), class = "data.frame", row.names = c(NA, -10L))

#df$m <- sapply(seq_len(nrow(df)), function(i)m[df$V1[i], df$V2[i]])
df$m <- m[as.matrix(df)]  # Use matrix subsetting, suggested by @Aaron
df

   V1 V2 m
1   3  3 9
2   3  2 8
3   3  3 9
4   3  3 9
5   3  3 9
6   3  3 9
7   2  3 6
8   1  2 2
9   2  2 5
10  3  3 9
于 2011-05-04T17:02:35.063 回答
5

Andrie 已经通过展示解决您问题的更好方法来回答您的问题。但是我想提一下您的原始代码中的一些错误。

第一,&不一样&&。查看?'&'更多。我相信你想&在你的例子中使用。

其次,==用于相等性测试,您最初在示例中正确使用了它。它不用于分配,您在将“9”分配给 时错误地使用它x[3]。赋值由 处理<-,无论是内部函数还是外部函数。查看?'=='?'<-'了解更多信息。

x[3]第三,在函数内赋值是apply()没有意义的。 apply()只是返回一个数组。它不会修改OXT对象。以下是您的原始方法的外观示例。但是,Andrie 的方法可能更适合您。

OXT <- read.table(textConnection(
    "3 3
    3 2
    3 3
    3 3
    3 3
    3 3
    2 3
    1 2
    2 2
    3 3"))
colnames(OXT)<- c("OXT1","OXT2")

OXT$HAP <- apply(OXT, 1, function(x)
    {
        if(x[1] == 3 & x[2] == 3) result <- 9
        else if(x[1] == 3 & x[2] == 2) result <- 8
        else if(x[1] == 3 & x[2] == 1) result <- 7
        else result <- 0
        return(result)
    })
于 2011-05-04T17:31:22.327 回答
5

不幸的是,我来晚了,解决方案类似于@Andrie 的解决方案,如下所示:

dat <- matrix(c(3,3,3,2,3,3,3,3,3,3,3,3,2,3,1,2,2,2,3,3), 
              nr=10, byrow=TRUE) 
# here is our lookup table for genotypes
pat <- matrix(1:9, nr=3, byrow=T, dimnames=list(1:3,1:3))

然后

> pat[dat]
 [1] 9 8 9 9 9 9 6 2 5 9

给你你想要的。

但是,我想说的是,您可能会发现更容易使用专门的包进行基因研究,例如在CRAN(例如geneticsgapSNPassoc,仅举几例)或Bioconductor上发现的包,因为它们包括用于转换/重新编码基因型数据和使用单倍型。

这是我对上述评论的想法的一个例子:

> library(genetics)
> geno1 <- as.genotype.allele.count(dat[,1]-1)
> geno2 <- as.genotype.allele.count(dat[,2]-1)
> table(geno1, geno2)
     geno2
geno1 A/A A/B
  A/A   6   1
  A/B   1   1
  B/B   0   1
于 2011-05-04T17:28:39.860 回答
3

另一种方法是将两列粘贴在一起并制作一个因子。

df <- structure(list(V1 = c(3L, 3L, 3L, 3L, 3L, 3L, 2L, 1L, 2L, 3L), 
        V2 = c(3L, 2L, 3L, 3L, 3L, 3L, 3L, 2L, 2L, 3L)), .Names = c("V1", 
        "V2"), class = "data.frame", row.names = c(NA, -10L))

df$hap <- factor(paste(df$V1, df$V2, sep=""))

或者等价地,

df$hap2 <- factor(apply(df[1:2], 1, paste, collapse=""))
于 2011-05-04T17:37:36.137 回答