从同一数据帧中减去数据帧的子集

时间:2016-07-19 11:53:32

标签: r dataframe subset

我有一个以下结构的数据框: 它可能有多个行和列

v<-c("control", NA, 1, 2, 4, "test", NA, 1, 2, 4, "test", NA, 1, 2, 4, "test", NA, 1, 2, 4)
df<- as.data.frame(t(matrix(v, nrow=5, ncol=4)))
colnames(df)<-c("ID", "G1", "G2", "G3", "G4")
df
       ID   G1 G2 G3 G4
1 control <NA>  1  2  4
2    test <NA>  1  2  4
3    test <NA>  1  2  4
4    test <NA>  1  2  4

我想从其他行中减去ID == control的行,给出以下结果:

result
           ID   G1 G2 G3 G4
    1    test <NA>  0  0  0
    2    test <NA>  0  0  0
    3    test <NA>  0  0  0

我尝试了sweep()函数,我尝试通过for循环,但没有任何效果。

如果有人可以帮助我,那将是惊人的。 谢谢!

2 个答案:

答案 0 :(得分:2)

假设只有一个“控件”,根据'control'值('i1')创建一个逻辑索引,将'ID'的'df'子集不是'control'('df1' ),使用Map从'ID'为'control'的相同列中减去'df1'中的列,并将输出分配给'df1'中的相应列。

i1 <- df$ID=="control"
df1 <- df[!i1,]
df1[3:5] <- Map(`-`, df1[3:5], df[i1,3:5])
df1
#    ID   G1 G2 G3 G4
#2 test <NA>  0  0  0
#3 test <NA>  0  0  0
#4 test <NA>  0  0  0

或者不是使用Map我们可以复制以使两个数据集的长度相等并进行减法

df1[3:5] <- df1[3:5] - df[i1, 3:5][col(df1[3:5])]

数据

df[-(1:2)] <- lapply(df[-(1:2)], function(x) as.numeric(as.character(x)))

答案 1 :(得分:1)

好吧,您可以使用sweep之类的

sweep(df[!df$ID == "control", ][3:5],2,
                         as.numeric(as.vector(df[df$ID == "control", ][3:5])))


#   G2 G3 G4
#2   0  0  0
#3   0  0  0
#4   0  0  0

假设只有一行IDcontrol。您可以将没有ID的行作为control进行子集化,并将其作为控件的ID行减去它。 as.numeric(as.vector(df[df$ID == "control", ][3:5]))将其转换为要减去的向量。