计算top& R中多列中的最低百分之十的值

时间:2016-04-22 15:31:14

标签: r function subset rbind

加载库和样本数据:

library(MASS)
View(Cars93)
Cars93$ID=1:93

现在我想要对Cars93进行分组,以便新的df(sub0lsub0h)包含所有列的所有ID,但只有top(对于df sub0h)和第17:25列中最低10%的值(对于df sub0l),其余值(对于df sub0l为11-100四分位数,对于df sub0h为0-90四分位数)可以更改到NA。

这是我尝试从第17:25列创建两个前十%或最低十%值的dfs:

sub0l <- do.call(rbind,by (Cars93,Cars93$ID,FUN= function(x) 
  subset(Cars93, (Cars93[,17:25] <= quantile(Cars93[,17:25], probs=  .10)))))

sub0h <- do.call(rbind,by (Cars93,Cars93$ID,FUN= function(x) 
  subset(Cars93, (Cars93[,17:25] >= quantile(Cars93[,17:25], probs=  .91)))))

在输入列的最高和最低十分位数时出错:

Error in `[.data.frame`(Cars93, ,17:25) : undefined columns selected
Called from: `[.data.frame`(Cars93, ,17:25)

还有更好的选择吗?

1 个答案:

答案 0 :(得分:2)

我认为以下内容会返回您要找的内容

sub0l <- cbind(Cars93[,1:16], sapply(Cars93[,17:25], 
                  function(i) ifelse(i > quantile(i, probs=0.1, na.rm=T) | is.na(i), NA, i)))

sub0h <- cbind(Cars93[,1:16], sapply(Cars93[,17:25], 
                 function(i) ifelse(i < quantile(i, probs=0.91, na.rm=T) | is.na(i), NA, i)))

sapply函数循环遍历data.frame中应用了分位数函数的每个变量。在每次传递中,泛型函数通过“i”参数将变量作为向量访问。然后将其传递给ifelse函数。该函数查看向量的每个元素,并评估它是否通过了测试。如果元素通过测试,则为其分配NA,如果失败,则返回其原始值。此过程适用于数字变量。

如果某些变量不是数字,那么您可以在sapply函数中添加额外的检查,如下所示:

sub0l <- cbind(Cars93[,1:16], 
               sapply(Cars93[,17:25], 
                 function(i) {
                   if(is.numeric(i)) {
                     ifelse(i > quantile(i, probs=0.1, na.rm=T) | is.na(i), NA, i)))
                   }
                   else i
                 }))

sub0h <- cbind(Cars93[,1:16], 
               sapply(Cars93[,17:25],
                 function(i) {
                   if(is.numeric(i)) {
                     ifelse(i < quantile(i, probs=0.91, na.rm=T) | is.na(i), NA, i)
                   }
                   else i
                 }))

在开始上述操作之前,泛型函数检查向量i是否为numeric类型(在R中,这是模式double或integer,请参阅?typeof以讨论R中的核心元素类型)。如果此测试失败,则向量将由else i返回。如果第一次测试通过,则上述过程开始。