R Cut()错误-';中断';它们不是独一无二的
我有以下数据帧:R Cut()错误-';中断';它们不是独一无二的,r,R,我有以下数据帧: 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.
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)
})
当我将以下代码应用于此数据帧时:
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)
})
但是,相同的代码在类似的数据帧上工作得非常好:
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]
varnames之所以会出现此错误,是因为数据中b.1
、a.2
和b.2
列的分位数值对于某些级别是相同的,因此它们不能直接用作函数cut()
中的断点值
解决此问题的一种方法是将quantile()
放入unique()
函数中,这样您将删除所有非唯一的分位数值。如果分位数不是唯一的,这当然会减少断点
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]
res如果你想保持分位数的数量,另一个选择是只添加一点抖动,例如
breaks = c(-Inf,quantile(a[,paste(i,1,sep=".")], na.rm=T),Inf)
breaks = breaks + seq_along(breaks) * .Machine$double.eps
您可以使用.bincode而不是cut,它接受非唯一的中断向量。如果您说的是十分位数、四分位数等,实际上是指人口的10%或25%,而不是十分位数/四分位数桶的实际数值,您可以先对值进行排序,并在列组上应用分位数
函数:
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)
a_ranks <- rank(a, ties.method = "first")
decile <- cut(a_ranks, quantile(a_ranks, probs=0:10/10), include.lowest=TRUE, labels=FALSE)
a