按行删除某些特定索引之前的值
Removing values prior to some specific index rowwise
我目前的数据如下所示:
ID
Var_1
Var_2
Var_3
Var_4
Var_5
RemovePrior
1
20
30
25
35
40
3
2
40
50
45
55
60
2
3
60
70
65
75
80
4
4
80
90
85
95
85
5
df <- data.frame(ID = c(1, 2, 3, 4),
Var_1 = c(20, 40, 60, 80),
Var_2 = c(30, 50, 70, 90),
Var_3 = c(25, 45, 65, 85),
Var_4 = c(35, 55, 75, 95),
Var_5 = c(40, 60, 80, 85),
RemovePrior = c(3, 2, 4, 5))
我的目标是——对于每一行——用带有 NA 的“RemovePrior”表示的后缀填充变量左侧的变量。例如,对于 ID = 1,RemovePrior 的值为 3,因此我希望将 Var_1 和 Var_2 设置为 NA。以下是预期结果:
ID
Var_1
Var_2
Var_3
Var_4
Var_5
RemovePrior
1
NA
NA
25
35
40
3
2
NA
50
45
55
60
2
3
NA
NA
NA
75
80
4
4
NA
NA
NA
NA
85
5
可能的解决方案:
library(tidyverse)
df %>%
mutate(across(Var_1:Var_5,
~ if_else(which(cur_column() == names(df[-1])) < RemovePrior, NA_real_, .x)))
#> ID Var_1 Var_2 Var_3 Var_4 Var_5 RemovePrior
#> 1 1 NA NA 25 35 40 3
#> 2 2 NA 50 45 55 60 2
#> 3 3 NA NA NA 75 80 4
#> 4 4 NA NA NA NA 85 5
我们可以使用base R
nm1 <- startsWith(names(df), "Var")
df[nm1] <- NA^(col(df[nm1]) < df$RemovePrior) * df[nm1]
-输出
> df
ID Var_1 Var_2 Var_3 Var_4 Var_5 RemovePrior
1 1 NA NA 25 35 40 3
2 2 NA 50 45 55 60 2
3 3 NA NA NA 75 80 4
4 4 NA NA NA NA 85 5
或 dplyr
library(dplyr)
df %>%
mutate(across(starts_with("Var_"),
~ case_when(readr::parse_number(cur_column()) >= RemovePrior ~ .x )))
ID Var_1 Var_2 Var_3 Var_4 Var_5 RemovePrior
1 1 NA NA 25 35 40 3
2 2 NA 50 45 55 60 2
3 3 NA NA NA 75 80 4
4 4 NA NA NA NA 85 5
这是我们可以做到的另一种方法:
使用 pivot_longer
和 pivot_wider
library(dplyr)
library(tidyr)
df %>%
pivot_longer(
-c(ID, RemovePrior)
) %>%
group_by(ID) %>%
mutate(value = ifelse(value == lag(value, unique(RemovePrior)-1), NA, value)) %>%
pivot_wider(
names_from = name,
values_from = value
)
输出:
ID RemovePrior Var_1 Var_2 Var_3 Var_4 Var_5
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 3 NA NA 25 35 40
2 2 2 NA 50 45 55 60
3 3 4 NA NA NA 75 80
4 4 5 NA NA NA NA 85
我目前的数据如下所示:
ID | Var_1 | Var_2 | Var_3 | Var_4 | Var_5 | RemovePrior |
---|---|---|---|---|---|---|
1 | 20 | 30 | 25 | 35 | 40 | 3 |
2 | 40 | 50 | 45 | 55 | 60 | 2 |
3 | 60 | 70 | 65 | 75 | 80 | 4 |
4 | 80 | 90 | 85 | 95 | 85 | 5 |
df <- data.frame(ID = c(1, 2, 3, 4),
Var_1 = c(20, 40, 60, 80),
Var_2 = c(30, 50, 70, 90),
Var_3 = c(25, 45, 65, 85),
Var_4 = c(35, 55, 75, 95),
Var_5 = c(40, 60, 80, 85),
RemovePrior = c(3, 2, 4, 5))
我的目标是——对于每一行——用带有 NA 的“RemovePrior”表示的后缀填充变量左侧的变量。例如,对于 ID = 1,RemovePrior 的值为 3,因此我希望将 Var_1 和 Var_2 设置为 NA。以下是预期结果:
ID | Var_1 | Var_2 | Var_3 | Var_4 | Var_5 | RemovePrior |
---|---|---|---|---|---|---|
1 | NA | NA | 25 | 35 | 40 | 3 |
2 | NA | 50 | 45 | 55 | 60 | 2 |
3 | NA | NA | NA | 75 | 80 | 4 |
4 | NA | NA | NA | NA | 85 | 5 |
可能的解决方案:
library(tidyverse)
df %>%
mutate(across(Var_1:Var_5,
~ if_else(which(cur_column() == names(df[-1])) < RemovePrior, NA_real_, .x)))
#> ID Var_1 Var_2 Var_3 Var_4 Var_5 RemovePrior
#> 1 1 NA NA 25 35 40 3
#> 2 2 NA 50 45 55 60 2
#> 3 3 NA NA NA 75 80 4
#> 4 4 NA NA NA NA 85 5
我们可以使用base R
nm1 <- startsWith(names(df), "Var")
df[nm1] <- NA^(col(df[nm1]) < df$RemovePrior) * df[nm1]
-输出
> df
ID Var_1 Var_2 Var_3 Var_4 Var_5 RemovePrior
1 1 NA NA 25 35 40 3
2 2 NA 50 45 55 60 2
3 3 NA NA NA 75 80 4
4 4 NA NA NA NA 85 5
或 dplyr
library(dplyr)
df %>%
mutate(across(starts_with("Var_"),
~ case_when(readr::parse_number(cur_column()) >= RemovePrior ~ .x )))
ID Var_1 Var_2 Var_3 Var_4 Var_5 RemovePrior
1 1 NA NA 25 35 40 3
2 2 NA 50 45 55 60 2
3 3 NA NA NA 75 80 4
4 4 NA NA NA NA 85 5
这是我们可以做到的另一种方法:
使用 pivot_longer
和 pivot_wider
library(dplyr)
library(tidyr)
df %>%
pivot_longer(
-c(ID, RemovePrior)
) %>%
group_by(ID) %>%
mutate(value = ifelse(value == lag(value, unique(RemovePrior)-1), NA, value)) %>%
pivot_wider(
names_from = name,
values_from = value
)
输出:
ID RemovePrior Var_1 Var_2 Var_3 Var_4 Var_5
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 1 3 NA NA 25 35 40
2 2 2 NA 50 45 55 60
3 3 4 NA NA NA 75 80
4 4 5 NA NA NA NA 85