英文:
Check the previous row and find when the number change to zero in R
问题
您想要创建一个名为 pre_dur
的新列,其中包含以 dur_
开头的变量的前一行的最后一个非负值。以下是一个通用的代码示例,可以处理不同的 dur_
变量:
library(dplyr)
d1 <- d %>%
mutate(pre_dur = {
dur_columns <- select(., starts_with("dur_"))
row_indices <- rowSums(dur_columns > 0)
pre_dur <- sapply(1:nrow(d), function(i) {
if (row_indices[i] > 0) {
last_nonnegative <- tail(which(dur_columns[i,] > 0), 1)
if (length(last_nonnegative) > 0) {
return(dur_columns[i, last_nonnegative])
}
}
return(NA)
})
return(pre_dur)
})
这段代码将适用于具有不同数字后缀的 dur_
变量,并为每一行计算 pre_dur
。
英文:
I have a data like this:
d <- data.frame(
ab = c(3, 4, 2, 6),
dur_1 = c(32, 1, 3, 4),
dur_2 = c(27, 9, 26, 5),
dur_3 = c(25, 8, 21, 48),
dur_5 = c(0, 4, 0, 42),
dur_6 = c(0, 0, 0, 0),
dur_7 = c(0, 0, 0, 0),
cd = c(45, 67, 34, 78)
)
What I want to do is make a new column pre_dur
.
pre_dur
is the last nonnegative value of previous rows for the variables starts with dur_
.
So, to get pre_dur
, scan through the dur_
variables in the previous row, find where the number starts to change zero. The very last nonnegative number is the value that I want.
My expected output should be like this:
d1<-data.frame(ab=c(3,4,2,6),
dur_1=c(32,1,3,4),
dur_2=c(27,9,26,5),
dur_3=c(25,8,21,48),
dur_5=c(0,4,0,42),
dur_6=c(0,0,0,0),
dur_7=c(0,0,0,0),
cd=c(45,67,34,78),
pre_dur=c(NA,25,4,21))
Actually the code below works:
d1 <- d %>%
mutate(pre_dur = case_when(lag(dur_7) > 0 ~ lag(dur_7),
lag(dur_6) > 0 ~ lag(dur_6),
lag(dur_5) > 0 ~ lag(dur_5),
lag(dur_3) > 0 ~ lag(dur_3),
lag(dur_2) > 0 ~ lag(dur_2),
lag(dur_1) > 0 ~ lag(dur_1),
TRUE ~ NA_real_))
However, in my actual data, the natural number after dur_
can be changed. So I need a generalized code. How to do that?
答案1
得分: 2
以下是翻译好的代码部分:
library(tidyverse)
temp <- d %>%
pivot_longer(-ab) %>%
group_by(ab) %>%
mutate(out = ifelse(value == 0, lag(value), 0)) %>%
filter(out != 0)
bind_cols(d, pre_dur = lag(temp$out))
这段代码假设一旦数值降至0,就不再增加。如果不是这种情况,那么 ifelse
语句需要进行相应修改。
英文:
How about this solution?
library(tidyverse)
temp <- d %>%
pivot_longer(-ab) %>%
group_by(ab) %>%
mutate(out = ifelse(value == 0, lag(value), 0)) %>%
filter(out != 0)
# bind_cols(d, pre_dur = c(NA, temp$out[2:nrow(temp)]))
bind_cols(d, pre_dur = lag(temp$out))
This assumes that once a value drops to 0, then it doesn't increase. If this isn't the case, then the ifelse
statement needs to capture this.
答案2
得分: 1
以下是您要翻译的内容:
首先,找到每个组的值,然后将其滞后一次。我们可以使用 rowwise()
来实现,但将其转换为长格式然后再转换回来可能会更快速且更易读。即:
library(dplyr)
library(tidyr)
d |>
pivot_longer(starts_with("dur")) |>
mutate(pre_dur = last(value[value > 0]), .by = "ab") |>
pivot_wider() |>
mutate(pre_dur = lag(pre_dur))
# 一个 tibble: 4 × 9
ab cd pre_dur dur_1 dur_2 dur_3 dur_5 dur_6 dur_7
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 3 45 NA 32 27 25 0 0 0
2 4 67 25 1 9 8 4 0 0
3 2 34 4 3 26 21 0 0 0
4 6 78 21 4 5 48 42 0 0
英文:
First, find the value for each group, then, lag it once. We could do it using rowwise()
, but it's probably faster and more readable to transform it into long format and back again. I.e.
library(dplyr)
library(tidyr)
d |>
pivot_longer(starts_with("dur")) |>
mutate(pre_dur = last(value[value > 0]), .by = "ab") |>
pivot_wider() |>
mutate(pre_dur = lag(pre_dur))
# A tibble: 4 × 9
ab cd pre_dur dur_1 dur_2 dur_3 dur_5 dur_6 dur_7
<dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 3 45 NA 32 27 25 0 0 0
2 4 67 25 1 9 8 4 0 0
3 2 34 4 3 26 21 0 0 0
4 6 78 21 4 5 48 42 0 0
答案3
得分: 1
A way in base using max.col
with last
.
i <- which(startsWith(names(d), "dur"))
j <- max.col(d[i] > 0, "last")
cbind(d, pre_dur = c(NA, d[cbind(seq_len(nrow(d)), i[j])][-nrow(d)]))
# ab dur_1 dur_2 dur_3 dur_5 dur_6 dur_7 cd pre_dur
#1 3 32 27 25 0 0 0 45 NA
#2 4 1 9 8 4 0 0 67 25
#3 2 3 26 21 0 0 0 34 4
#4 6 4 5 48 42 0 0 78 21
英文:
A way in base using max.col
with last
.
i <- which(startsWith(names(d), "dur"))
j <- max.col(d[i] > 0, "last")
cbind(d, pre_dur = c(NA, d[cbind(seq_len(nrow(d)), i[j])][-nrow(d)]))
# ab dur_1 dur_2 dur_3 dur_5 dur_6 dur_7 cd pre_dur
#1 3 32 27 25 0 0 0 45 NA
#2 4 1 9 8 4 0 0 67 25
#3 2 3 26 21 0 0 0 34 4
#4 6 4 5 48 42 0 0 78 21
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论