R -

2016-03-21 25 views
0

koşullarına bağlı olarak, veri çerçevesindeki her bir çift için bir çift satırdan birini kaldırın Verileri işlemek için bir komut dosyası yazıyorum ve bir veri kümesinden kaldırılan bir çift satırdan birine ihtiyacım var. Aşağıdaki örnekte, birinci dilüsyonu (saniyeden daha küçük olacak) 20,000'in altında tutmayı, ancak 2. seyreltmeyi ikinci dilüsyonun ne olursa olsun 20.000'in üzerinde ise 2. seyreltmeyi seçmeyi istiyorum. Tam dilüsyon değerleri veri kümesinden veri kümesine değişir, ancak her bir hasta için asla iki dilüsyondan daha fazla olmayacaktır, bu yüzden her zaman en düşük dilüsyonunu ilk olarak 20.000 eşiğine karşı aynı kalacak şekilde kontrol etmek istiyorum. Ayrıca bu veri seti, meta verileri içeren çok sayıda sütun içeriyor.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 

Kodumun geri kalanına bakmak isterseniz, burası (evet, bir noob'dur). satırlara

###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

kullanımına gerek "En düşük" değil, "20000’in altındaysa ilk ** dilüsyonunu devam ettir" demek istediğini düşünüyorum. – alistaire

cevap

3
dplyr, group_by hasta ile

ve filter (gruplandırılmış-hastaya) aşağıdaki koşulu sağladığı bu. Durum, first,imum ise lastValue değerini döndürür.

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 

Not: bu yaklaşım söz konusu sonuçlanan data.frame dönmek olmazdı sorusuna, lafzını izler. durum o 20000 altında ise, ilk seyreltme dönmek gerekiyorduysa yapmanız gereken tüm first için min değiştirmek olduğunu ve sorudan sonuç veri çerçevesini almak:

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

Burada bir hata yaptığınızı düşünüyorum, "Dilüsyon" "Değer" olmalı, "Dilüsyon" değişkeni sadece görebildiğimiz kadarıyla "2" ve "20" ye sahip. –

+0

Sadece düzenlenmiş; Soruyu yanlış anladım ve cevabımı çok çabuk çözmeye çalıştım. – alistaire

+0

Bu harika, güzel ve basit bir teşekkür! 20.000'in altındaysa ilk dilüsyonu iade etmek demek istedim. Onu en düşük olarak nitelendirdim çünkü her zaman son dilüsyondan daha küçük bir sayı olacak ve sıraya girmeyecek ama bunun nasıl kafa karıştırıcı olduğunu görebiliyorum. – AwesomeeExpress

1

Biz kullanabilirsiniz data.table. 'Data.frame' öğesini 'Patient' ile gruplandırarak 'Patient.Frame' (setDT(df)) 'a dönüştürün, last bir tane varsa, min' Value 'ile satırları ayırmak için if/else koşulunu kullanırız. koşul first "Değeri" dayalı ise

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 

biz first(Value) veya Value[1L] için min(Value) gelen değişiklikler yapabilir ve ayrıca 1 yerine which.min

sonuçlarınız data.frame itibaren
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

Teşekkür ederim bu harika! İlk dilüsyondan bahsetmiştim, ancak ilk dilüsyon her zaman ikinci dilüsyondan daha küçük bir sayı olacak, ancak onlar ilk sırada sizin yerine ilk örneklemi kullanacağımı düşünmemek için sıraya giremeyebilirler. – AwesomeeExpress