我有一个df:
a<-c('TSPAN6','DPM1','SCYL3')
b<-c(0.1,0.001,0.0002)
c<-c(0.01,0.01,0.001)
d<-c(-0.5,1.3,-1.7)
df<-data.frame(a,b,c,d)
names(df)<- c('gene', 'p-val','padj','lfc')
我想根据其他列的条件创建一个新列。 像这样:
if (df$p-val < 0.01){
df$new == 'black'
} else if (df$p-val<0.01 & df$padj < 0.01 & df$lfc<0) {
df$new == 'blue'
} else if (df$p-val < 0.01 & df$padj < 0.01 & df$lfc > 0) {
df$new =='red'
} else {
df$new =='grey'
}
这不起作用,我得到
我看过与此类似的帖子,但答案似乎总是使用'elsif'代替,但我看不到如何在两个以上的条件下使用'elsif'?
条件的长度> 1,并且仅使用第一个元素
答案 0 :(得分:2)
您可以使用within
来操纵数据帧的变量,而无需始终使用df$
对其进行引用。在括号[
中创建一个逻辑子集(尝试使用df$p.val < 0.01
),总共只有TRUE
成为向量的子集(位于[
的正前方,例如new[...]
)。通过分配<-
,您可以设置一切都交给"black"
。
df <- within(df, {
new <- "grey"
new[p.val < 0.01] <- "black"
new[p.val < 0.01 & padj < 0.01 & lfc > 0] <- "blue"
new[p.val < 0.01 & padj < 0.01 & lfc > 0] <- "red"
})
df
# gene p.val padj lfc new
# 1 TSPAN6 1e-01 0.010 -0.5 grey
# 2 DPM1 1e-03 0.010 1.3 black
# 3 SCYL3 2e-04 0.001 -1.7 black
注意 ,您尝试的代码存在一些问题。您说df$new == 'black'
,但实际上是指df$new = 'black'
。 ==
和=
之间有很好的区别。 ==
比较两个元素,而=
分配从右到左;这就是为什么我们更愿意使用<-
而不是=
进行分配的原因,因为它使这一点更加清楚。使用=
设置参数的函数例外。
@ mischva11 也已指出使用-
,+
,:
,/
,*
等运算符等不是一个好主意,在R中我们改用.
。还要避免使用前导数字,例如20.sample
会带来很多麻烦。
数据
df <- structure(list(gene = structure(c(3L, 1L, 2L), .Label = c("DPM1",
"SCYL3", "TSPAN6"), class = "factor"), p.val = c(0.1, 0.001,
2e-04), padj = c(0.01, 0.01, 0.001), lfc = c(-0.5, 1.3, -1.7)), class = "data.frame", row.names = c(NA,
-3L))