数据行,变量和值在计算期间重新排序

时间:2015-03-18 14:46:42

标签: r

在绘图之前将数据添加到矩阵时,我遇到了问题:

> resFile <- read.csv("file.csv")
> print(resFile)
     Gene Virus  Expression    Percentage
1    ga   1Virus 2.738598e-02  38.590745
2    ga   2Virus 3.247252e-02  64.331929
3    ga   PIC    4.235604e-02  114.348940
4    ga   MOCK   1.976032e-02  0.000000        
> samples <- unique(resFile$Virus)
> genes <- unique(resFile$Gene)
> numGene <- length(genes)
> numSmpl <- length(samples)

> mat <- matrix(ncol=numGene,nrow=numSmpl,dimnames=list(samples,genes))
> mat[samples,genes]<-resFile$Percentage
> print(mat)
              ga 
1Virus  38.59074
2Virus  64.33193
PIC      0.00000
MOCK   114.34894

如您所见,percentage值在我的PIC和MOCK样本之间切换。这也发生在整列上,看起来这些值是按字母顺序而不是按字母顺序添加的。

为什么会发生这种情况?我该如何解决这个问题?

2 个答案:

答案 0 :(得分:2)

你在这里遇到了一些问题:

mat[samples,genes] <- resFile$Percentage

首先,如果samplesgenes来自resFile,它们可能是因素而非字符串,因此如果samplesgenes的顺序不同于您将获得洗牌的行或列的因子级别的顺序。

其次,这会将resFile$Percentage分配给mat的所有子集,其中行名称位于samples,列名称位于genes,而不是将它们成对。

要解决这些问题,请尝试以下方法(我假设您如何生成samplesgenes

resFile <- data.frame(Gene="ga",
                      Virus=c("1Virus","2Virus","PIC","MOCK"),          
                      Percentage=c(38.59,64.33,114.34,0))
samples <- unique(resFile$Virus)
genes <- unique(resFile$Gene)
numGene <- length(genes)
numSmpl <- length(samples)
mat <- matrix(ncol=numGene,nrow=numSmpl,dimnames=list(samples,genes))

mat[cbind(as.character(resFile$Virus)),as.character(resFile$Gene)] <- resFile$Percentage
mat
#            ga
# 1Virus  38.59
# 2Virus  64.33
# PIC    114.34
# MOCK     0.00

关键的区别在于我已经将因子变量转换为字符,并使用矩阵而不是两个向量进行索引 - 请参阅?'['以获得有关数组索引的更好解释,而不是我可以管理。

答案 1 :(得分:1)

你只会感到奇怪,因为你在CSV中读到了令人恼火的默认stringsAsFactors() = TRUE 。因此,所有字符串列都成为因子,而且它们使用默认的factor(..., ordered=F)。您可以将它们作为字符串阅读,然后根据需要转换为factor(..., ordered=T)

然后,每当你看到有人从unique(df$factorCol)构建一个矩阵/向量而不是labels()时,你会重新审视该排序问题,除非该因子是有序的。

在你的情况下你甚至不需要创建矩阵,你可以直接从数据帧切片中获取x,y系列resFile[, c('Virus','Percentage')]

resFile <- read.csv("res.csv", stringsAsFactors=F)

resFile[, c('Virus','Percentage')]
   Virus Percentage
1 1Virus   38.59074
2 2Virus   64.33193
3    PIC  114.34894
4   MOCK    0.00000

> as.matrix(resFile[, c('Virus','Percentage')])
     Virus    Percentage 
[1,] "1Virus" " 38.59074"
[2,] "2Virus" " 64.33193"
[3,] "PIC"    "114.34894"
[4,] "MOCK"   "  0.00000"
# Creating a matrix from slices of dataframe isn't desirable, not just for the row-ordering, but also because all entries are coerced to string. So just don't do it.

现在,如果您想要为每个Gene获取一个组,那么只选择Virus,Percentage列,使用dplyr:

> require(dplyr)
> ga_slice <- resFile %>% group_by(Gene) %>% select(Virus,Percentage) %>% ungroup() %>% select(-Gene)
Source: local data frame [4 x 2]

   Virus Percentage
1 1Virus   38.59074
2 2Virus   64.33193
3    PIC  114.34894
4   MOCK    0.00000