创建在特定值之前和之后的倒计时和计数器。

huangapple go评论103阅读模式
英文:

Create countdown and counter before and after a certain value

问题

以下是您要翻译的代码部分:

  1. I want to create a variable that counts down a given number of steps before certain value and counts up a given number steps after the value.
  2. In the example below, I want to have a counters before and after the `grp == "b"`. When `grp == "b"` the value should be 0, and before and after the counters it should be 100.
  3. [![enter image description here][1]][1]
  4. To do this I can use case_when function as follows:
  5. library(dplyr)
  6. n<-10;k<-3
  7. test_df<-data.frame(id=1:(k*n),grp=rep(letters[1:k],each=n))
  8. before=5;after=3;index=2
  9. test_df2<-test_df %>%
  10. mutate(before_after=
  11. case_when(
  12. grp == letters[index] ~ 0
  13. ,dplyr::lag(grp,1) == letters[index] ~ 1
  14. ,dplyr::lag(grp,2) == letters[index] ~ 2
  15. ,dplyr::lag(grp,3) == letters[index] ~ 3
  16. ,dplyr::lead(grp,1) == letters[index] ~ -1
  17. ,dplyr::lead(grp,2) == letters[index] ~ -2
  18. ,dplyr::lead(grp,3) == letters[index] ~ -3
  19. ,dplyr::lead(grp,4) == letters[index] ~ -4
  20. ,dplyr::lead(grp,5) == letters[index] ~ -5
  21. ,TRUE~100
  22. )
  23. )
  1. The problem is the variables "before" and "after" are not static! So I should make a function to do it as follows:
  2. b_a<-function(before=15,after=6,others=100,grp_f=letters[2]){
  3. }
  1. How to make a function to do it?
  2. Edit:
  3. I created a function but if there us a better and easy solution please feel free to add an answer:
  4. b_a<-unction(test_df,before=15,after=6,others=100,grp_f=letters[2]){
  5. ltr<-grp_f
  6. test_df2<- test_df %>%
  7. group_by(grp) %>%
  8. dplyr::mutate( fr=ifelse(grp==ltr,dplyr::first(id),0 )) %>%
  9. ungroup() %>%
  10. dplyr::mutate( fr=max(fr)) %>%
  11. mutate(fr=-(fr-id)) %>%
  12. mutate(fr=ifelse(fr<0,fr,0 ))
  13. test_df2<- test_df2 %>%
  14. group_by(grp) %>%
  15. dplyr::mutate( lst=ifelse(grp==ltr,dplyr::last(id),0 )) %>%
  16. ungroup() %>%
  17. dplyr::mutate( lst=max(lst)) %>%
  18. mutate(lst=-(lst-id)) %>%
  19. mutate(lst=ifelse(lst>0,lst,0 ))
  20. test_df2<- test_df2 %> ungroup() %>%
  21. mutate(before_after=lst+fr)
  22. test_df2 %> mutate(ifelse(before_after >= -before &
  23. before_after <=after,before_after,others))
  24. test_df2
  25. }
  1. This may help:
  2. test_df3<-test_df %>%
  3. group_by(grp) %>%
  4. mutate(is_group_b=ifelse(grp==letters[index],1,0)) %>%
  5. ungroup() %>%
  6. mutate(nr=row_number()) %>%
  7. mutate(nr=nr*is_group_b) %>%
  8. mutate(max_nr=max(nr))%>%
  9. mutate(nr=ifelse(nr==0,NA,nr)) %>%
  10. mutate(min_nr=min(nr,na.rm = TRUE)) %>%
  11. mutate(nr=ifelse(is.na(nr),0,nr)) %>%
  12. mutate(vl=(row_number()-min_nr)) %>%
  13. mutate(vl=vl*(1-is_group_b)) %>%
  14. mutate(vl=if_else(vl>0,row_number()-max_nr,vl))

请注意,我已经去掉了HTML转义字符",使代码更易阅读。

英文:

I want to create a variable that counts down a given number of steps before certain value and counts up a given number steps after the value.

In the example below, I want to have a counters before and after the grp == "b". When grp == "b" the value should be 0, and before and after the counters it should be 100.

创建在特定值之前和之后的倒计时和计数器。

To do this I can use case_when function as follows:

  1. library(dplyr)
  2. n<-10;k<-3
  3. test_df<-data.frame(id=1:(k*n),grp=rep(letters[1:k],each=n))
  4. before=5;after=3;index=2
  5. test_df2<-test_df %>%
  6. mutate(before_after=
  7. case_when(
  8. grp == letters[index] ~ 0
  9. ,dplyr::lag(grp,1) == letters[index] ~ 1
  10. ,dplyr::lag(grp,2) == letters[index] ~ 2
  11. ,dplyr::lag(grp,3) == letters[index] ~ 3
  12. ,dplyr::lead(grp,1) == letters[index] ~ -1
  13. ,dplyr::lead(grp,2) == letters[index] ~ -2
  14. ,dplyr::lead(grp,3) == letters[index] ~ -3
  15. ,dplyr::lead(grp,4) == letters[index] ~ -4
  16. ,dplyr::lead(grp,5) == letters[index] ~ -5
  17. ,TRUE~100
  18. )
  19. )

The problem is the variables "before" and "after" are not static! So I should make a function to do it as follows:

  1. b_a<-function(before=15,after=6,others=100,grp_f=letters[2]){
  2. }

How to make a function to do it?

Edit:

I created a function but if there us a better and easy solution please feel free to add an answer:

  1. b_a<-unction(test_df,before=15,after=6,others=100,grp_f=letters[2]){
  2. ltr<-grp_f
  3. test_df2<- test_df %>%
  4. group_by(grp) %>%
  5. dplyr::mutate( fr=ifelse(grp==ltr,dplyr::first(id),0 )) %>%
  6. ungroup() %>%
  7. dplyr::mutate( fr=max(fr)) %>%
  8. mutate(fr=-(fr-id)) %>%
  9. mutate(fr=ifelse(fr<0,fr,0 ))
  10. test_df2<- test_df2 %>%
  11. group_by(grp) %>%
  12. dplyr::mutate( lst=ifelse(grp==ltr,dplyr::last(id),0 )) %>%
  13. ungroup() %>%
  14. dplyr::mutate( lst=max(lst)) %>%
  15. mutate(lst=-(lst-id)) %>%
  16. mutate(lst=ifelse(lst>0,lst,0 ))
  17. test_df2<- test_df2 %>% ungroup() %>%
  18. mutate(before_after=lst+fr)
  19. test_df2 %>% mutate(ifelse(before_after >= -before &
  20. before_after <=after,before_after,others))
  21. test_df2
  22. }

This may help:

  1. test_df3<-test_df %>%
  2. group_by(grp) %>%
  3. mutate(is_group_b=ifelse(grp==letters[index],1,0)) %>%
  4. ungroup() %>%
  5. mutate(nr=row_number()) %>%
  6. mutate(nr=nr*is_group_b) %>%
  7. mutate(max_nr=max(nr))%>%
  8. mutate(nr=ifelse(nr==0,NA,nr)) %>%
  9. mutate(min_nr=min(nr,na.rm = TRUE)) %>%
  10. mutate(nr=ifelse(is.na(nr),0,nr)) %>%
  11. mutate(vl=(row_number()-min_nr)) %>%
  12. mutate(vl=vl*(1-is_group_b)) %>%
  13. mutate(vl=if_else(vl>0,row_number()-max_nr,vl))

答案1

得分: 1

以下是代码的中文翻译:

  1. # 导入dplyr库
  2. library(dplyr)
  3. # 使用管道操作符 %>%
  4. # 根据列"grp"分组
  5. test_df %>%
  6. group_by(grp) %>%
  7. # 根据条件改变列"value"的值
  8. mutate(value = ifelse(grp == letters[index-1] & row_number() <= 5, 100, (before:1)*-1),
  9. value1 = ifelse(grp == letters[index+1] & row_number() > 3, 100, 1:after)) %>%
  10. # 根据条件改变列"value"的值,使用case_when函数
  11. mutate(value = case_when(grp == letters[index] ~ 0,
  12. grp == letters[index-1] ~ value,
  13. grp == letters[index+1] ~ value1), .keep="unused") %>%
  14. # 打印前50行
  15. print(n=50)
  1. id grp value
  2. <int> <chr> <dbl>
  3. 1 1 a 100
  4. 2 2 a 100
  5. 3 3 a 100
  6. 4 4 a 100
  7. 5 5 a 100
  8. 6 6 a -5
  9. 7 7 a -4
  10. 8 8 a -3
  11. 9 9 a -2
  12. 10 10 a -1
  13. 11 11 b 0
  14. 12 12 b 0
  15. 13 13 b 0
  16. 14 14 b 0
  17. 15 15 b 0
  18. 16 16 b 0
  19. 17 17 b 0
  20. 18 18 b 0
  21. 19 19 b 0
  22. 20 20 b 0
  23. 21 21 c 1
  24. 22 22 c 2
  25. 23 23 c 3
  26. 24 24 c 100
  27. 25 25 c 100
  28. 26 26 c 100
  29. 27 27 c 100
  30. 28 28 c 100
  31. 29 29 c 100
  32. 30 30 c 100
英文:

Try this:

  1. library(dplyr)
  2. test_df %&gt;%
  3. group_by(grp) %&gt;%
  4. mutate(value = ifelse(grp == letters[index-1] &amp; row_number() &lt;= 5, 100, (before:1)*-1),
  5. value1 = ifelse(grp == letters[index+1] &amp; row_number() &gt; 3, 100, 1:after)) %&gt;%
  6. mutate(value = case_when(grp == letters[index] ~ 0,
  7. grp == letters[index-1] ~ value,
  8. grp == letters[index+1] ~ value1), .keep=&quot;unused&quot;) %&gt;%
  9. print(n=50)
  1. id grp value
  2. &lt;int&gt; &lt;chr&gt; &lt;dbl&gt;
  3. 1 1 a 100
  4. 2 2 a 100
  5. 3 3 a 100
  6. 4 4 a 100
  7. 5 5 a 100
  8. 6 6 a -5
  9. 7 7 a -4
  10. 8 8 a -3
  11. 9 9 a -2
  12. 10 10 a -1
  13. 11 11 b 0
  14. 12 12 b 0
  15. 13 13 b 0
  16. 14 14 b 0
  17. 15 15 b 0
  18. 16 16 b 0
  19. 17 17 b 0
  20. 18 18 b 0
  21. 19 19 b 0
  22. 20 20 b 0
  23. 21 21 c 1
  24. 22 22 c 2
  25. 23 23 c 3
  26. 24 24 c 100
  27. 25 25 c 100
  28. 26 26 c 100
  29. 27 27 c 100
  30. 28 28 c 100
  31. 29 29 c 100
  32. 30 30 c 100

答案2

得分: 1

将结果列设置为100。获取焦点组的索引。创建给定长度的替代值(countdown - zeros - countup)。在相关的索引处替换结果。

  1. d = data.frame(id = 1:12, grp = rep(letters[1:3], each = 4))
  2. before = 2
  3. after = 3
  4. g = "b"
  5. d$x = 100
  6. i = which(d$grp == g)
  7. v = c(-before:-1, rep(0, length(i)), seq(after))
  8. d$x = replace(d$x, i[1] - before + 0:(length(v) - 1), v)
  9. d
  10. # id grp x
  11. # 1 1 a 100
  12. # 2 2 a 100
  13. # 3 3 a -2
  14. # 4 4 a -1
  15. # 5 5 b 0
  16. # 6 6 b 0
  17. # 7 7 b 0
  18. # 8 8 b 0
  19. # 9 9 c 1
  20. # 10 10 c 2
  21. # 11 11 c 3
  22. # 12 12 c 100

根据数据的不同,您可能需要添加一个检查,以确保before和after序列的索引保持在数据范围内,例如使用%in%

  1. d = data.frame(id = 1:8, grp = rep(letters[1:3], c(1, 5, 2)))
  2. before = 2
  3. after = 3
  4. g = "b"
  5. d$x = 100
  6. i = which(d$grp == g)
  7. v = c(-before:-1, rep(0, length(i)), seq(after))
  8. i2 = i[1] - before + 0:(length(v) - 1)
  9. ok = i2 %in% seq_len(nrow(d)) # 检查索引是否在数据范围内
  10. d$x = replace(d$x, i2[ok], v[ok])
  11. d
  12. # id grp x
  13. # 1 1 a -1 # 前导倒计时被截断
  14. # 2 2 b 0
  15. # 3 3 b 0
  16. # 4 4 b 0
  17. # 5 5 b 0
  18. # 6 6 b 0
  19. # 7 7 c 1
  20. # 8 8 c 2 # 尾部计数器被截断
英文:

Set result column to 100. Get indices of the focal group. Create replacement values (countdown - zeros - countup) of given lengths. Replace result at relevant indices.

  1. d = data.frame(id = 1:12, grp = rep(letters[1:3], each = 4))
  2. before = 2
  3. after = 3
  4. g = &quot;b&quot;
  5. d$x = 100
  6. i = which(d$grp == g)
  7. v = c(-before:-1, rep(0, length(i)), seq(after))
  8. d$x = replace(d$x, i[1] - before + 0:(length(v) - 1), v)
  9. d
  10. # id grp x
  11. # 1 1 a 100
  12. # 2 2 a 100
  13. # 3 3 a -2
  14. # 4 4 a -1
  15. # 5 5 b 0
  16. # 6 6 b 0
  17. # 7 7 b 0
  18. # 8 8 b 0
  19. # 9 9 c 1
  20. # 10 10 c 2
  21. # 11 11 c 3
  22. # 12 12 c 100

Depending on the data, you may want to add a check so that indices of before- and after-sequences are kept within the bounds of the data, e.g. using %in%:

  1. d = data.frame(id = 1:8, grp = rep(letters[1:3], c(1, 5, 2)))
  2. before = 2
  3. after = 3
  4. g = &quot;b&quot;
  5. d$x = 100
  6. i = which(d$grp == g)
  7. v = c(-before:-1, rep(0, length(i)), seq(after))
  8. i2 = i[1] - before + 0:(length(v) - 1)
  9. ok = i2 %in% seq_len(nrow(d)) # &lt;~ check if indices are within range of data
  10. d$x = replace(d$x, i2[ok], v[ok])
  11. d
  12. # id grp x
  13. # 1 1 a -1 # leading countdown truncated
  14. # 2 2 b 0
  15. # 3 3 b 0
  16. # 4 4 b 0
  17. # 5 5 b 0
  18. # 6 6 b 0
  19. # 7 7 c 1
  20. # 8 8 c 2 # trailing counter truncated

huangapple
  • 本文由 发表于 2023年2月19日 13:58:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75498280.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定