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)
时,它没有对数据框进行任何更改,我不明白为什么。
谢谢!
您可以使用 apply
和 ifelse
来执行此操作。见下文:
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
我在大型数据框(大约 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)
时,它没有对数据框进行任何更改,我不明白为什么。
谢谢!
您可以使用 apply
和 ifelse
来执行此操作。见下文:
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