如何在 r 中使用 if 条件基于其他列创建新列
How to create a new column based on other columns with if conditions in r
无法找到基于列中事件组的 if 条件生成新列的方法。
名为 "BF" 的列代表流列的 (i-3),并且对于每个 "event" 组将是相同的 BF。例如,在第5行中,"BF"的值为39,这是事件列中所有“2”的流列(第2行的流)的前第三个值。
问题是 BF[i] 不能大于 flow[i]。如果 BF[i] 大于 flow[i],则 BF 应该是流的 (i-4) 或 (i-5) 或 (1-6)... 直到 BF[i] 等于或小于 flow[i]。例如,在第 10 行中,"BF" 列的值大于 "flow" 列的值,因此,第 10 行中 BF_1(我要创建的列)的值是 37,表示最接近的 flow 的较低值,在本例中是 flow[i-6].
例如,我们有以下数据框:
flow<- c(40, 39, 38, 37, 50, 49, 46, 44, 43, 45, 40, 30, 80, 75, 50, 55, 53, 51, 49, 100)
event<- c(1,1,1,1,2,2,2,2,2,3,3,3,4,4,4,5,5,5,5,6)
BF<- c(NA, NA, NA, NA, 39, 39, 39, 39, 39, 46, 46, 46, 45, 45, 45, 80, 80, 80, 80, 53)
a<- data.frame(flow, event, BF)
这就是我正在寻找的愿望输出。我想创建 BF_1 列。
flow event BF BF_1
1 40 1 NA NA
2 39 1 NA NA
3 38 1 NA NA
4 37 1 NA NA
5 50 2 39 39
6 49 2 39 39
7 46 2 39 39
8 44 2 39 39
9 43 2 39 39
10 45 3 46 37
11 40 3 46 37
12 30 3 46 37
13 80 4 45 45
14 75 4 45 45
15 50 4 45 45
16 55 5 80 30
17 53 5 80 30
18 51 5 80 30
19 49 5 80 30
20 100 6 53 53
是否有可能生成列 BF_1?请让我知道任何想法。我正在使用 for 循环并使用 if 条件,但我无法保留整个事件列组的 BF 值。
编码效率有点低,可以使用 dplyr 等..,但它会完成工作并匹配给定的 BF_1
列
flow <- c(40, 39, 38, 37, 50, 49, 46, 44, 43, 45, 40, 30, 80, 75, 50, 55, 53, 51, 49, 100)
event <- c(1,1,1,1,2,2,2,2,2,3,3,3,4,4,4,5,5,5,5,6)
BF <- c(NA, NA, NA, NA, 39, 39, 39, 39, 39, 46, 46, 46, 45, 45, 45, 80, 80, 80, 80, 53)
a <- data.frame(flow, event, BF)
a$BF_1 <- NA #default to NA first
for(i in 1:length(unique(a$event))){
if(is.na(a[a$event == i, "BF"][1])) next
if(a[a$event == i, "BF"][1] < a[a$event == i, "flow"][1]) a[a$event == i, "BF_1"] <- a[a$event == i, "BF"][1]
if(a[a$event == i, "BF"][1] > a[a$event == i, "flow"][1]) {
head <- min(which(a$event==i))-6
if (min(head-6) < 0) head <- 1 #making sure it doesn't overflow to row 0
a[a$event == i, "BF_1"] <- min( a[ head:min(which(a$event==i)), "flow"] ) #fill the min of the subset flow column given position
}
}
a
一个 tidyverse
可能性是:
a %>%
left_join(crossing(a, a) %>%
filter(event > event1) %>%
group_by(event) %>%
filter(flow == first(flow)) %>%
slice(1:(n() - 3)) %>%
slice(which.max(cumsum(flow > flow1))) %>%
ungroup() %>%
transmute(event,
flow_flag = flow1), by = c("event" = "event")) %>%
mutate(BF_1 = ifelse(lag(flow, 3) > flow, flow_flag, lag(flow, 3))) %>%
group_by(event) %>%
mutate(BF_1 = first(BF_1)) %>%
select(-flow_flag)
flow event BF BF_1
<dbl> <dbl> <dbl> <dbl>
1 40 1 NA NA
2 39 1 NA NA
3 38 1 NA NA
4 37 1 NA NA
5 50 2 39 39
6 49 2 39 39
7 46 2 39 39
8 44 2 39 39
9 43 2 39 39
10 45 3 46 37
11 40 3 46 37
12 30 3 46 37
13 80 4 45 45
14 75 4 45 45
15 50 4 45 45
16 55 5 80 30
17 53 5 80 30
18 51 5 80 30
19 49 5 80 30
20 100 6 53 53
它可能过于复杂,但它所做的是首先创建值的所有组合(因为所需值理论上可以在数据中的任何位置)。其次,它确定每组满足条件的第一个案例(不考虑之前的第三个值)。最后,它将它与原始 df 结合起来,如果每组的前 3 个值满足条件,则 returns 它,否则 returns 值首先满足条件小于实际值。
无法找到基于列中事件组的 if 条件生成新列的方法。
名为 "BF" 的列代表流列的 (i-3),并且对于每个 "event" 组将是相同的 BF。例如,在第5行中,"BF"的值为39,这是事件列中所有“2”的流列(第2行的流)的前第三个值。 问题是 BF[i] 不能大于 flow[i]。如果 BF[i] 大于 flow[i],则 BF 应该是流的 (i-4) 或 (i-5) 或 (1-6)... 直到 BF[i] 等于或小于 flow[i]。例如,在第 10 行中,"BF" 列的值大于 "flow" 列的值,因此,第 10 行中 BF_1(我要创建的列)的值是 37,表示最接近的 flow 的较低值,在本例中是 flow[i-6].
例如,我们有以下数据框:
flow<- c(40, 39, 38, 37, 50, 49, 46, 44, 43, 45, 40, 30, 80, 75, 50, 55, 53, 51, 49, 100)
event<- c(1,1,1,1,2,2,2,2,2,3,3,3,4,4,4,5,5,5,5,6)
BF<- c(NA, NA, NA, NA, 39, 39, 39, 39, 39, 46, 46, 46, 45, 45, 45, 80, 80, 80, 80, 53)
a<- data.frame(flow, event, BF)
这就是我正在寻找的愿望输出。我想创建 BF_1 列。
flow event BF BF_1
1 40 1 NA NA
2 39 1 NA NA
3 38 1 NA NA
4 37 1 NA NA
5 50 2 39 39
6 49 2 39 39
7 46 2 39 39
8 44 2 39 39
9 43 2 39 39
10 45 3 46 37
11 40 3 46 37
12 30 3 46 37
13 80 4 45 45
14 75 4 45 45
15 50 4 45 45
16 55 5 80 30
17 53 5 80 30
18 51 5 80 30
19 49 5 80 30
20 100 6 53 53
是否有可能生成列 BF_1?请让我知道任何想法。我正在使用 for 循环并使用 if 条件,但我无法保留整个事件列组的 BF 值。
编码效率有点低,可以使用 dplyr 等..,但它会完成工作并匹配给定的 BF_1
列
flow <- c(40, 39, 38, 37, 50, 49, 46, 44, 43, 45, 40, 30, 80, 75, 50, 55, 53, 51, 49, 100)
event <- c(1,1,1,1,2,2,2,2,2,3,3,3,4,4,4,5,5,5,5,6)
BF <- c(NA, NA, NA, NA, 39, 39, 39, 39, 39, 46, 46, 46, 45, 45, 45, 80, 80, 80, 80, 53)
a <- data.frame(flow, event, BF)
a$BF_1 <- NA #default to NA first
for(i in 1:length(unique(a$event))){
if(is.na(a[a$event == i, "BF"][1])) next
if(a[a$event == i, "BF"][1] < a[a$event == i, "flow"][1]) a[a$event == i, "BF_1"] <- a[a$event == i, "BF"][1]
if(a[a$event == i, "BF"][1] > a[a$event == i, "flow"][1]) {
head <- min(which(a$event==i))-6
if (min(head-6) < 0) head <- 1 #making sure it doesn't overflow to row 0
a[a$event == i, "BF_1"] <- min( a[ head:min(which(a$event==i)), "flow"] ) #fill the min of the subset flow column given position
}
}
a
一个 tidyverse
可能性是:
a %>%
left_join(crossing(a, a) %>%
filter(event > event1) %>%
group_by(event) %>%
filter(flow == first(flow)) %>%
slice(1:(n() - 3)) %>%
slice(which.max(cumsum(flow > flow1))) %>%
ungroup() %>%
transmute(event,
flow_flag = flow1), by = c("event" = "event")) %>%
mutate(BF_1 = ifelse(lag(flow, 3) > flow, flow_flag, lag(flow, 3))) %>%
group_by(event) %>%
mutate(BF_1 = first(BF_1)) %>%
select(-flow_flag)
flow event BF BF_1
<dbl> <dbl> <dbl> <dbl>
1 40 1 NA NA
2 39 1 NA NA
3 38 1 NA NA
4 37 1 NA NA
5 50 2 39 39
6 49 2 39 39
7 46 2 39 39
8 44 2 39 39
9 43 2 39 39
10 45 3 46 37
11 40 3 46 37
12 30 3 46 37
13 80 4 45 45
14 75 4 45 45
15 50 4 45 45
16 55 5 80 30
17 53 5 80 30
18 51 5 80 30
19 49 5 80 30
20 100 6 53 53
它可能过于复杂,但它所做的是首先创建值的所有组合(因为所需值理论上可以在数据中的任何位置)。其次,它确定每组满足条件的第一个案例(不考虑之前的第三个值)。最后,它将它与原始 df 结合起来,如果每组的前 3 个值满足条件,则 returns 它,否则 returns 值首先满足条件小于实际值。