2013-04-24 13 views
26

Ben dataframe aşağıdakilere sahip benzersiz değildir: Bu dataframe için aşağıdaki kodu uyguladığınızdaKes() hatası - 'tatili'

a   
    ID a.1 b.1  a.2 b.2 
1 1 40.00 100.00 NA 88.89 
2 2 100.00 100.00 100 100.00 
3 3 50.00 100.00 75 100.00 
4 4 66.67 59.38 NA 59.38 
5 5 37.50 100.00 NA 100.00 
6 6 100.00 100.00 100 100.00 

:

temp <- do.call(rbind,strsplit(names(df)[-1],".",fixed=TRUE)) 
dup.temp <- temp[duplicated(temp[,1]),] 

res <- lapply(dup.temp[,1],function(i) { 
breaks <- c(-Inf,quantile(a[,paste(i,1,sep=".")], na.rm=T),Inf) 
cut(a[,paste(i,2,sep=".")],breaks) 
}) 

kesme() işlevi, bir verir hata:

Error in cut.default(a[, paste(i, 2, sep = ".")], breaks) : 
'breaks' are not unique 

Ancak aynı kod benzer dataframe üzerinde de mükemmel çalışıyor:

varnames<-c("ID", "a.1", "b.1", "c.1", "a.2", "b.2", "c.2") 

a <-matrix (c(1,2,3,4, 5, 6, 7), 2,7) 

colnames (a)<-varnames 

df<-as.data.frame (a) 


    ID a.1 b.1 c.1 a.2 b.2 c.2 
    1 1 3 5 7 2 4 6 
    2 2 4 6 1 3 5 7 

res <- lapply(dup.temp[,1],function(i) { 
breaks <- c(-Inf,quantile(a[,paste(i,1,sep=".")], na.rm=T),Inf) 
cut(a[,paste(i,2,sep=".")],breaks) 
}) 

res 
[[1]] 
[1] (-Inf,3] (-Inf,3] 
Levels: (-Inf,3] (3,3.25] (3.25,3.5] (3.5,3.75] (3.75,4] (4, Inf] 

[[2]] 
[1] (-Inf,5] (-Inf,5] 
Levels: (-Inf,5] (5,5.25] (5.25,5.5] (5.5,5.75] (5.75,6] (6, Inf] 

[[3]] 
[1] (5.5,7] (5.5,7] 
Levels: (-Inf,1] (1,2.5] (2.5,4] (4,5.5] (5.5,7] (7, Inf] 

Bu hatanın nedeni nedir? Nasıl düzeltilebilir? Teşekkür ederiz. sütunlar b.1, a.2 ve b.2 için verilerinde kantil değerler bazı düzeyleri için aynı olduğu için

cevap

24

Bu hatayı olsun, bu yüzden doğrudan fonksiyonu cut() kesilmeler değerler olarak kullanılamaz. Bu sorunu çözmek için

apply(a,2,quantile,na.rm=T) 
     ID  a.1 b.1 a.2  b.2 
0% 1.00 37.5000 59.38 75.0 59.3800 
25% 2.25 42.5000 100.00 87.5 91.6675 
50% 3.50 58.3350 100.00 100.0 100.0000 
75% 4.75 91.6675 100.00 100.0 100.0000 
100% 6.00 100.0000 100.00 100.0 100.0000 

Tek yön unique() işlevi içinde quantile() koymak olurdu - benzersiz olmayan tüm kantil değerleri kaldıracaktır böylece. Bu, eğer miktarlar benzersiz değilse, daha az kırılma noktaları yaratacaktır.

res <- lapply(dup.temp[,1],function(i) { 
    breaks <- c(-Inf,unique(quantile(a[,paste(i,1,sep=".")], na.rm=T)),Inf) 
    cut(a[,paste(i,2,sep=".")],breaks) 
}) 

[[1]] 
[1] <NA>  (91.7,100] (58.3,91.7] <NA>  <NA>  (91.7,100] 
Levels: (-Inf,37.5] (37.5,42.5] (42.5,58.3] (58.3,91.7] (91.7,100] (100, Inf] 

[[2]] 
[1] (59.4,100] (59.4,100] (59.4,100] (-Inf,59.4] (59.4,100] (59.4,100] 
Levels: (-Inf,59.4] (59.4,100] (100, Inf] 
+0

Çok teşekkür ederim, Didzis Elferts! Şimdi her şey anlaşıldı. – DSSS

7

Bunun yerine quantiles sayısını kalmasını istiyorsanız, başka bir seçenek sadece, örneğin titreşim biraz eklemektir

breaks = c(-Inf,quantile(a[,paste(i,1,sep=".")], na.rm=T),Inf) 
breaks = breaks + seq_along(breaks) * .Machine$double.eps 
7

Kesmek yerine, benzersiz bir kırılma eşleşmesini kabul eden .bincode'u kullanabilirsiniz. Eğer dilimde, quartile vb gerçekte nüfusun% 10 veya% 25 bölümlerini ve burada dilimde/quartile kovalar değil gerçek sayısal değerler anlamına eğer derken

2

şunu kullanabilirsiniz budur:

a <- c(1,1,1,2,3,4,5,6,7,7,7,7,99,0.5,100,54,3,100,100,100,11,11,12,11,0) 
ar<-rank(a,ties.method = "first") 
decile <- cut(ar, quantile(ar, probs=0:10/10), include.lowest=TRUE, labels=FALSE) 
İlgili konular