如何在保留行名称的同时对向量进行子集化?

How do I subset a vector while retaining row names?

我正在寻找数据集中差异表达的基因。在使用我的函数确定倍数变化后,我得到了一个向量,其中 returns 基因名称和倍数变化如下所示:

df1
               [,1]
gene1074  1.1135131
gene22491 1.0668137
gene15416 0.9840414
gene18645 1.1101060
gene4068  1.0055899
gene19043 1.1463878

我想寻找变化大于 2 倍的任何东西,为此我执行:

df2 <- subset(df1 >= 2)

其中returns以下:

head(df2)
           [,1]
gene1074  FALSE
gene22491 FALSE
gene15416 FALSE
gene18645 FALSE
gene4068  FALSE
gene19043 FALSE

这不是我要找的。

我尝试了另一种子集化方法:

df2 <- df1[df1 >= 2]

哪个returns:

head(df2)
[1]   4.191129 127.309557   2.788121   2.090916  11.382345   2.186330

现在这是大于 2 的值,但我丢失了与它们一起出现的基因名称。

我将如何对我的数据进行子集化,使其 returns 采用以下格式:

head(df2)
          [,1]
genex   4.191129
geney   127.309557 
genez   2.788121
genea   2.090916
geneb   11.382345

或者至少近似于给我基因的格式及其对应的倍数变化值

您正在寻找这样的子集:

df2 <- df1[df1[, 1] >= 2, ]

向您展示一些数据:

# Create some toy data
df1 <- data.frame(val = rexp(100))
rownames(df1) <- paste0("gene", 1:100)
head(df1)
#            val
#gene1 0.9295632
#gene2 1.2090513
#gene3 0.1550578
#gene4 1.7934942
#gene5 0.7286462
#gene6 1.8424025

现在我们取 df1 的第一列并与 2 (df1[,1] > 2) 进行比较。该输出(逻辑向量)用于 select 满足条件的行:

df2 <- df1[df1[,1] > 2, ]
head(df2)
#[1] 2.705683 3.410672 3.544905 3.695313 2.523586 2.229879

使用 drop = FALSE 将输出保持为 data.frame:

df3 <- df1[df1[,1] > 2, ,drop = FALSE]
head(df3)
#            val
#gene8  2.705683
#gene9  3.410672
#gene22 3.544905
#gene23 3.695313
#gene38 2.523586
#gene42 2.229879

同样可以通过

实现
subset(df1, subset = val > 2)

subset(df1, subset = df1[1,] > 2)

这两个表达式中的前者在您的情况下不起作用,因为您似乎没有命名列。

您还可以计算数据中与您的谓词相对应的位置,并将它们用于索引:

# create some test data
df <- read.csv(
  textConnection(
    "g, v
    gene1074, 1.1135131
    gene22491, 1.0668137
    gene15416, 0.9840414
    gene18645, 1.1101060
    gene4068, 1.0055899
    gene19043, 1.1463878"
  ))

# positions that match a given predicate
idx <- which(df$v > 1)

# indexing "as usual"
df[idx, ]

输出:

              g        v
1      gene1074 1.113513
2     gene22491 1.066814
4     gene18645 1.110106
5      gene4068 1.005590
6     gene19043 1.146388

我发现这段代码读起来非常好并且非常直观,但这可能只是我的意见。