如何在数据框中找到前 n% 的记录并将其更改为 1,否则为 0

How to find top n% of records in a dataframe and change it to 1, otherwise 0

我有这样一个数据框:

v1 v2 v2 v4 v5 v6 v7 v8
1  10 8  8  50 19 41 20
11 21 87 67 23 49 14 0
88 24 55 67 24 67 56 90

我想要的是,如果值在所有值的前5%或10%,则改为1; 如果不是,则替换为 0。 结构如下:(这不是真实的结果,只是显示我想要得到的结构)

0  0 0  0  1 0 0 1
0  0 1  0  0 0 0 1
0  1 0  0  1 0 0 1

有什么快速的方法吗?我的数据大约是60*639

这个有用吗:

df
# A tibble: 3 x 8
     v1    v2  v2_1    v4    v5    v6    v7    v8
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     1    10     8     8    50    19    41    20
2    11    21    87    67    23    49    14     0
3    88    24    55    67    24    67    56    90
df[] <- lapply(df, function(x) +(x > quantile(sort(unlist(df)), 0.95, names = F)))
df
# A tibble: 3 x 8
     v1    v2  v2_1    v4    v5    v6    v7    v8
  <int> <int> <int> <int> <int> <int> <int> <int>
1     0     0     0     0     0     0     0     0
2     0     0     0     0     0     0     0     0
3     1     0     0     0     0     0     0     1

在基数 R 中:

1*(as.matrix(df) > quantile(unlist(df), 0.95))
#>      v1 v2 v2.1 v4 v5 v6 v7 v8
#> [1,]  0  0    0  0  0  0  0  0
#> [2,]  0  0    0  0  0  0  0  0
#> [3,]  1  0    0  0  0  0  0  1

另一种选择是将数据透视值延长,然后按组排列。较低的前 5 个将分配在前 5 行。然后你计算一个二进制变量并重塑为宽(不确定前 5 个是否可以理解为前 5 个元素或其他东西。我也通过某种意义上的“行”进行了计算):

library(dplyr)
library(tidyr)
#Function
newdf <- df %>% mutate(id=row_number()) %>%
  pivot_longer(-id) %>%
  arrange(id,value) %>%
  group_by(id) %>%
  mutate(Var=ifelse(row_number()<=5,0,1)) %>%
  select(-value) %>%
  pivot_wider(names_from=name,values_from=Var) %>%
  ungroup() %>% select(-id)

输出:

# A tibble: 3 x 8
     v1    v3    v4    v2    v6    v8    v7    v5
  <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1     0     0     0     0     0     1     1     1
2     0     1     1     0     1     0     0     0
3     1     0     0     0     1     1     0     0

一个dplyr选项可以是:

df %>%
 mutate(across(everything(), ~ as.numeric(. > quantile(unlist(df), 0.95))))

  v1 v2 v2.1 v4 v5 v6 v7 v8
1  0  0    0  0  0  0  0  0
2  0  0    0  0  0  0  0  0
3  1  0    0  0  0  0  0  1