R - 如果在 var 的前 x% 中,则用虚拟替换观察

R - Replace observations with dummy if in top x% of var

我在大型数据框(大约 80x300)中有一些数据,看起来像这样:

dum <- data.frame(id=c("a", "b", "c", "d", "e"),
                 v1=c(2, 7, 8, 5, 0),
                 v2=c(9, 2, 4, 6, 1),
                 v3=c(2, 2, 6, 1, 7))

我想将每个变量变成一个二分变量,指示每个特定观察值是否在每个变量的前 20% 中。 {稍后我将合并虚拟数据集和原始数据集,这目前并不重要,但如果有人想获得创意,那就是完整的计划。}现在输出数据帧应该如下所示:

id     v1     v2     v3
a      0      1      0
b      0      0      0
c      1      0      0
d      0      0      0
e      0      0      1

我的尝试如下所示:

top <- 20  # set percentage
for(i in 2:ncol(dum)) {
  for(j in 1:nrow(dum)) {
    ifelse(dum[j,i]>=unname(quantile(dum[,i],probs=((100-top)/100))), dum[j,i]<-1, dum[j,i]<-0)
  }
}

但是,当我 运行 这个命令时,在某些情况下,我最终在输出数据集中得到的数量比我想要的多,而在其他情况下,我得到的正是我想要的数量。它看起来不像我上面说的那样,而是像这样:

id     v1     v2     v3
a      0      1      0
b      0      0      0
c      1      0      0
d      1      1      0
e      0      1      1

任何人都可以帮助确定我哪里出错了吗?一些注意事项:1)我准备好因为使用循环而被讨厌,尤其是嵌套循环,但这是我熟悉的东西,计算时间在这里不是问题。 2) 根据我的谷歌搜索,似乎使用 apply 系列函数可能会有用,但我对它们不是很熟悉,所以我不知道从哪里开始。 3) 我包含了 unname() 命令作为尝试修复,但它 运行 有或没有它都是一样的。 4) ifelse() 语句的 YES/NO 部分在我看来很有趣,但是当我尝试执行 ifelse(cond, 1, 0) 时,它没有对数据框进行任何更改,我不明白为什么。

谢谢!

您可以使用 applyifelse 来执行此操作。见下文:

apply(dum[2:4],2,function(x) {ifelse(x>=quantile(x,.8),1,0)})

这个returns:

     v1 v2 v3
[1,]  0  1  0
[2,]  0  0  0
[3,]  1  0  0
[4,]  0  0  0
[5,]  0  0  1

请注意,我已使用 dum[2:4] 来确定相关列以进行条件测试。在使用完整数据集时,您应该将其修改为 select 仅您想要的相关列。

如果要将数据与原数据合并,可以添加:

dum2 = cbind(dum,apply(dum[2:4],2,function(x) {ifelse(x>=quantile(x,.8),1,0)}))

哪个returns:

  id v1 v2 v3 v1 v2 v3
1  a  2  9  2  0  1  0
2  b  7  2  2  0  0  0
3  c  8  4  6  1  0  0
4  d  5  6  1  0  0  0
5  e  0  1  7  0  0  1