我有一个以下结构的数据框: 它可能有多个行和列
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循环,但没有任何效果。
如果有人可以帮助我,那将是惊人的。 谢谢!
答案 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
假设只有一行ID
为control
。您可以将没有ID
的行作为control
进行子集化,并将其作为控件的ID
行减去它。 as.numeric(as.vector(df[df$ID == "control", ][3:5]))
将其转换为要减去的向量。