dplyr:通过迭代向量根据某些条件填充列
dplyr: Populating a column based on some condition by iterating over a vector
我正在寻找一种 tidyverse 解决方案,该解决方案通过迭代向量来根据某些条件填充列。
我想要一个整洁的解决方案,因为我的数据很大且嵌套,这与以下最小示例不同。
列 prev
表示系统的先前状态,new
表示新状态。 prev
和 new
始终按顺序排列,但其中一些可能会循环,如下例所示。
0
和 100
值是开始和结束状态,此处以字母表示的状态是重要的。
对于prev
和new
的某些组合(即同时满足prev_condition
和new_condition
),我需要迭代一个更大的向量vec
(它的元素多于可能的状态组合)并将值按顺序放在 to_do
列中
我想补充一点,prev
和 new
的组合不需要是唯一的,这就是为什么我添加列 change
来指示发生的每个状态变化.
这是一个最小的例子和一个基于 R 的解决方案。我真的希望有一个优雅的 tidyverse 解决方案。谢谢。
# Minimal reproducible data
df <- data.frame(prev = c("0", rep(letters[1:3], 2), rep(letters[4:10], 3)),
new = c(rep(letters[1:3], 2), rep(letters[4:10], 3), "100"),
change = 1:28,
to_do = rep(NA, 28))
# Vector for iteration
vec <- 1:30
# Conditions
prev_condition <- c(letters[4:6]) # prev state must be any of: "d" "e" "f"
new_condition <- c(letters[5:7]) # new state must be any of: "e" "f" "g"
# base R solution
n_row <- length(df[df$prev %in% prev_condition & df$new %in% new_condition, "to_do"])
df[df$prev %in% prev_condition & df$new %in% new_condition, "to_do"] <- vec[1:n_row]
df
#> prev new change to_do
#> 1 0 a 1 <NA>
#> 2 a b 2 <NA>
#> 3 b c 3 <NA>
#> 4 c a 4 <NA>
#> 5 a b 5 <NA>
#> 6 b c 6 <NA>
#> 7 c d 7 <NA>
#> 8 d e 8 I
#> 9 e f 9 Y
#> 10 f g 10 N
#> 11 g h 11 <NA>
#> 12 h i 12 <NA>
#> 13 i j 13 <NA>
#> 14 j d 14 <NA>
#> 15 d e 15 W
#> 16 e f 16 Q
#> 17 f g 17 Z
#> 18 g h 18 <NA>
#> 19 h i 19 <NA>
#> 20 i j 20 <NA>
#> 21 j d 21 <NA>
#> 22 d e 22 V
#> 23 e f 23 C
#> 24 f g 24 C
#> 25 g h 25 <NA>
#> 26 h i 26 <NA>
#> 27 i j 27 <NA>
#> 28 j 100 28 <NA>
由 reprex package (v2.0.1)
于 2022-05-09 创建
使用 dplyr
,我们可以使用 replace
创建列 - 创建一个 NA
向量和 replace
具有计数序列(sum
逻辑向量),其中该条件为 TRUE
library(dplyr)
df %>%
mutate(to_do = replace(rep(NA_real_, n()),
prev %in% prev_condition & new %in% new_condition,
seq_len(sum(prev %in% prev_condition & new %in% new_condition))))
-输出
prev new change to_do
1 0 a 1 NA
2 a b 2 NA
3 b c 3 NA
4 c a 4 NA
5 a b 5 NA
6 b c 6 NA
7 c d 7 NA
8 d e 8 1
9 e f 9 2
10 f g 10 3
11 g h 11 NA
12 h i 12 NA
13 i j 13 NA
14 j d 14 NA
15 d e 15 4
16 e f 16 5
17 f g 17 6
18 g h 18 NA
19 h i 19 NA
20 i j 20 NA
21 j d 21 NA
22 d e 22 7
23 e f 23 8
24 f g 24 9
25 g h 25 NA
26 h i 26 NA
27 i j 27 NA
28 j 100 28 NA
这对你有用吗:
library(dplyr)
df %>%
mutate(to_do = ifelse(new %in% new_condition &
prev %in% prev_condition, rank(to_do), to_do),
to_do = replace(to_do, !is.na(to_do),
seq_len(sum(!is.na(to_do)))))
prev new change to_do
1 0 a 1 NA
2 a b 2 NA
3 b c 3 NA
4 c a 4 NA
5 a b 5 NA
6 b c 6 NA
7 c d 7 NA
8 d e 8 1
9 e f 9 2
10 f g 10 3
11 g h 11 NA
12 h i 12 NA
13 i j 13 NA
14 j d 14 NA
15 d e 15 4
16 e f 16 5
17 f g 17 6
18 g h 18 NA
19 h i 19 NA
20 i j 20 NA
21 j d 21 NA
22 d e 22 7
23 e f 23 8
24 f g 24 9
25 g h 25 NA
26 h i 26 NA
27 i j 27 NA
28 j 100 28 NA
我正在寻找一种 tidyverse 解决方案,该解决方案通过迭代向量来根据某些条件填充列。 我想要一个整洁的解决方案,因为我的数据很大且嵌套,这与以下最小示例不同。
列 prev
表示系统的先前状态,new
表示新状态。 prev
和 new
始终按顺序排列,但其中一些可能会循环,如下例所示。
0
和 100
值是开始和结束状态,此处以字母表示的状态是重要的。
对于prev
和new
的某些组合(即同时满足prev_condition
和new_condition
),我需要迭代一个更大的向量vec
(它的元素多于可能的状态组合)并将值按顺序放在 to_do
我想补充一点,prev
和 new
的组合不需要是唯一的,这就是为什么我添加列 change
来指示发生的每个状态变化.
这是一个最小的例子和一个基于 R 的解决方案。我真的希望有一个优雅的 tidyverse 解决方案。谢谢。
# Minimal reproducible data
df <- data.frame(prev = c("0", rep(letters[1:3], 2), rep(letters[4:10], 3)),
new = c(rep(letters[1:3], 2), rep(letters[4:10], 3), "100"),
change = 1:28,
to_do = rep(NA, 28))
# Vector for iteration
vec <- 1:30
# Conditions
prev_condition <- c(letters[4:6]) # prev state must be any of: "d" "e" "f"
new_condition <- c(letters[5:7]) # new state must be any of: "e" "f" "g"
# base R solution
n_row <- length(df[df$prev %in% prev_condition & df$new %in% new_condition, "to_do"])
df[df$prev %in% prev_condition & df$new %in% new_condition, "to_do"] <- vec[1:n_row]
df
#> prev new change to_do
#> 1 0 a 1 <NA>
#> 2 a b 2 <NA>
#> 3 b c 3 <NA>
#> 4 c a 4 <NA>
#> 5 a b 5 <NA>
#> 6 b c 6 <NA>
#> 7 c d 7 <NA>
#> 8 d e 8 I
#> 9 e f 9 Y
#> 10 f g 10 N
#> 11 g h 11 <NA>
#> 12 h i 12 <NA>
#> 13 i j 13 <NA>
#> 14 j d 14 <NA>
#> 15 d e 15 W
#> 16 e f 16 Q
#> 17 f g 17 Z
#> 18 g h 18 <NA>
#> 19 h i 19 <NA>
#> 20 i j 20 <NA>
#> 21 j d 21 <NA>
#> 22 d e 22 V
#> 23 e f 23 C
#> 24 f g 24 C
#> 25 g h 25 <NA>
#> 26 h i 26 <NA>
#> 27 i j 27 <NA>
#> 28 j 100 28 <NA>
由 reprex package (v2.0.1)
于 2022-05-09 创建使用 dplyr
,我们可以使用 replace
创建列 - 创建一个 NA
向量和 replace
具有计数序列(sum
逻辑向量),其中该条件为 TRUE
library(dplyr)
df %>%
mutate(to_do = replace(rep(NA_real_, n()),
prev %in% prev_condition & new %in% new_condition,
seq_len(sum(prev %in% prev_condition & new %in% new_condition))))
-输出
prev new change to_do
1 0 a 1 NA
2 a b 2 NA
3 b c 3 NA
4 c a 4 NA
5 a b 5 NA
6 b c 6 NA
7 c d 7 NA
8 d e 8 1
9 e f 9 2
10 f g 10 3
11 g h 11 NA
12 h i 12 NA
13 i j 13 NA
14 j d 14 NA
15 d e 15 4
16 e f 16 5
17 f g 17 6
18 g h 18 NA
19 h i 19 NA
20 i j 20 NA
21 j d 21 NA
22 d e 22 7
23 e f 23 8
24 f g 24 9
25 g h 25 NA
26 h i 26 NA
27 i j 27 NA
28 j 100 28 NA
这对你有用吗:
library(dplyr)
df %>%
mutate(to_do = ifelse(new %in% new_condition &
prev %in% prev_condition, rank(to_do), to_do),
to_do = replace(to_do, !is.na(to_do),
seq_len(sum(!is.na(to_do)))))
prev new change to_do
1 0 a 1 NA
2 a b 2 NA
3 b c 3 NA
4 c a 4 NA
5 a b 5 NA
6 b c 6 NA
7 c d 7 NA
8 d e 8 1
9 e f 9 2
10 f g 10 3
11 g h 11 NA
12 h i 12 NA
13 i j 13 NA
14 j d 14 NA
15 d e 15 4
16 e f 16 5
17 f g 17 6
18 g h 18 NA
19 h i 19 NA
20 i j 20 NA
21 j d 21 NA
22 d e 22 7
23 e f 23 8
24 f g 24 9
25 g h 25 NA
26 h i 26 NA
27 i j 27 NA
28 j 100 28 NA