我有一个df:
df <- data.frame(genename = c("A","B","C","D"),
sample1 = c(10,0,50,0),
sample2 = c(0,30,0,70),
sample3 = c(50,0,0,30),
sample4 = c(0,0,0,10))
我想用至少50%的列提取行例如对于DF Genename A和D满足要求
我已经为所有专栏
解决了这个问题df2<-as.data.frame(df[apply(df ,MARGIN=1, function(x) all(x>0)),])
,但我无法为满足要求的列的一百分点而解决?
方法1
使用基本R的解决方案:
df[apply(df[, -1], 1, function(x) sum(x > 0) / length(x)) > 0.5, ]
# genename sample1 sample2 sample3 sample4
#1 A 10 0 50 70
#4 D 0 70 30 10
说明:基于>0
条目的百分比为>50%
的滤波行,除第一个列外。
方法2
使用dplyr
的解决方案:
df %>% mutate(frac = rowSums(.[-1] > 0) / length(.[-1])) %>% filter(frac > 0.5)
# genename sample1 sample2 sample3 sample4 frac
#1 A 10 0 50 70 0.75
#4 D 0 70 30 10 0.75
这是一个通用解决方案:
df <- data.frame(genename = c("A","B","C","D"),
sample1 = c(0,10,0,0), sample2 = c(10,30,50,0), sample3=c(0,40,50,10), sample4=c(0,40,0,10))
df[(rowSums(df[-1]>0))>= (ncol(df[-1])/2),]
# genename sample1 sample2 sample3 sample4
# 2 B 10 30 40 40
# 3 C 0 50 50 0
# 4 D 0 0 10 10
这将适用于您的基因名称的任何数据框架,并且您希望其他50%或更多的其他列具有非零值。
逻辑如下:
将数据帧从第二列开始:df[-1]
开始,然后将其转换为具有TRUE
的逻辑数据框,其中有一个大于0:df[-1]>0
的值。然后找出每行中有多少列具有TRUE
:rowSums(df[-1]>0)
。这返回一个长度nrow(df)
的向量,其值等于df
相应行的每个列中的非零值的数量。使用它来生成这些行的逻辑向量,其中至少一半的样品值大于0: rowSums(df[-1]>0) >= ncol(df[-1])/2
,并通过行子集df
来获取使表达式TRUE
的行。
尝试以下:
df[
apply( df[, -1], 1, function(x) sum(x>0)/length(x) > 0.5 ) ,
]
genename sample1 sample2 sample3 sample4
1 A 10 0 50 70
4 D 0 70 30 10