2016-03-21 65 views
0

我正在编写脚本来处理数据,并且需要从数据集中删除一对行之一。在下面的例子中,如果低于20,000,我想保留第一次稀释(总是小于第二次),但如果第一次稀释超过20,000,无论第二次稀释是多少,选择第二次稀释。确切的稀释值会因数据集的不同而不同,但每个患者的稀释度不会超过两次,因此我总是希望先检查最低稀释度,然后再对照20,000的阈值进行检测,结果保持不变。这个数据集也包含很多包含元数据的列。R - 根据条件删除数据帧中每对的一对行之一

Patient Dilution Value 
John  2   30000 
John  20   15000 
George 2   13000 
George 20   700 
Kelly  2   49000 
Kelly  20   24000 
Tom  2   80000 
Tom  20   30000 
Diane  2   700 
Diane  20   0 

Patient Dilution Value 
John  20   15000 
George 2   13000 
Kelly  20   24000 
Tom  20   30000 
Diane  2   700 

如果你想看看我的代码的其余部分是(是的,我是一个noob)。

###SA Summary 

sadf <- merge(mydata, elisadata, "Description", all.x = TRUE) 

sadf <- sadf[grep("X", sadf$Type),] 
sadf <- sadf[-grep("Blank", sadf$Name),] 
sadf <- sadf[-grep("MulV", sadf$Name),] 
sadf <- sadf[,c("Isotype","Name","Description","Dilution.x","FI-Bkgd-Neg","Error","Conc..ug.ml.")] 

sadf$Error <- as.character(sadf$Error) 
sadf$Error[sadf$Conc..ug.ml. < 0.05] <- "LC" 
sadf$Conc..ug.ml. <- ifelse(!is.na(sadf$Conc..ug.ml.) & sadf$Conc..ug.ml. < 0.05, NA, sadf$Conc..ug.ml.) 

sadf$SA <- with(sadf, sadf$`FI-Bkgd-Neg` * sadf$Dilution.x/sadf$Conc..ug.ml.) 

sadf$SA[sadf$SA < 0.02] <- 0.02 

if (unique(sadf$Dilution) > 1) {} ###Where I need to put the answer to the question 

sadf$`FI-Bkgd-Neg` <- NULL 
sadf$Error[is.na(sadf$Error)] <- 0 
sadf$Conc..ug.ml.[is.na(sadf$Conc..ug.ml.)] <- 0 
sadf <- reshape(sadf, idvar = c("Description","Dilution.x","Isotype","Error","Conc..ug.ml."), timevar = "Name", direction = "wide") 
sadf$Error[sadf$Error = 0] <- NA 
sadf$Conc..ug.ml.[sadf$Conc..ug.ml. = 0] <- NA 
+0

从结果data.frame,我认为你的意思是“如果低于20000,请保持**第一次稀释......”,而不是“最低”。 – alistaire

回答

3

随着dplyrgroup_by患者,然后filter于所述行(用于分组-由患者)满足条件。如果first超过20000,则条件返回lastValue,否则min即为。

library(dplyr) 
df %>% group_by(Patient) %>% filter(Value == ifelse(first(Value) > 20000, 
                last(Value), 
                min(Value))) 
# Source: local data frame [5 x 3] 
# Groups: Patient [5] 
# 
# Patient Dilution Value 
# (fctr) (int) (int) 
# 1 John  20 15000 
# 2 George  20 700 
# 3 Kelly  20 24000 
# 4  Tom  20 30000 
# 5 Diane  20  0 

注:这个方法如下的问题,这不会在这个问题返回结果data.frame的措辞。如果条件应该返回第一稀释如果是20000下,所有你需要做的是改变minfirst,和你从问题的结果数据帧:

df %>% group_by(Patient) %>% filter(Value == ifelse(first(Value) > 20000, 
                last(Value), 
                first(Value))) 
# Source: local data frame [5 x 3] 
# Groups: Patient [5] 
# 
# Patient Dilution Value 
# (fctr) (int) (int) 
# 1 John  20 15000 
# 2 George  2 13000 
# 3 Kelly  20 24000 
# 4  Tom  20 30000 
# 5 Diane  2 700 
+0

我认为你在这里有一个错误,“稀释”应该是“价值”,“稀释”变量只有“2”和“20”,据我们所知。 –

+0

刚刚编辑;我误解了这个问题,然后试图尽快解决我的问题。 – alistaire

+0

这是伟大的,很好,简单的感谢!我的意思是回到第一次稀释,如果它低于20,000。我把它称为最低,因为它总是比最后一次稀释的数字更小,并且可能不是为了顺序,但我看到了这是多么令人困惑。 – AwesomeeExpress

1

我们可以使用data.table。将'data.frame'转换为'data.table'(setDT(df)),按'患者'分组,我们使用if/else条件来对min'值'的行进行子集分类,如果存在其他分类则获得last

setDT(df1)[df1[ , .I[if(min(Value) <20000) 
     which.min(Value) else .N] , Patient]$V1] 
# Patient Dilution Value 
#1: John  20 15000 
#2: George  20 700 
#3: Kelly  20 24000 
#4:  Tom  20 30000 
#5: Diane  20  0 

如果条件是基于first“价值”,我们需要从min(Value)更改first(Value)Value[1L],还可以使用代替1 which.min

setDT(df1)[df1[ , .I[if(Value[1L] <20000) 
       1 else .N], Patient]$V1] 
# Patient Dilution Value 
#1: John  20 15000 
#2: George  2 13000 
#3: Kelly  20 24000 
#4:  Tom  20 30000 
#5: Diane  2 700 
+1

谢谢你太棒了!我的意思是第一次稀释,但第一次稀释比第二次稀释总是少一些,但它们可能不是这样,所以我想我会用第一个例子用min(稀释)代替。 – AwesomeeExpress

相关问题