问题描述
我的数据框如下:
library(dplyr)
df <- data.frame(A=1:20,B=c(2,1.8,1.6,4,6,8,10,12,13,14,15,16,16.5,13))
mutate(df,C = B - lag(B))
A B C
1 2.0 NA
2 1.8 -0.2
3 1.6 -0.2
4 1.8 0.2
5 4.0 2.2
6 6.0 2.0
7 8.0 2.0
8 10.0 2.0
9 12.0 2.0
10 10.0 -2.0
11 8.0 -2.0
12 6.0 -2.0
13 13.0 7.0
14 14.0 1.0
15 15.0 1.0
16 16.0 1.0
17 16.5 -0.5
18 15.0 -1.0
19 14.0 -1.0
20 13.0 -1.0
我想提取连续三个或三个以上的负值序列,并放在单独的列中。因此,例如,将(col C)行10、11、12中的值放在新列中,将行17、18、19、20中的值放在另一列中。这个数据帧很大,所以我不知道会有多少新列。任何帮助,将不胜感激。谢谢
解决方法
这里是rleid
的一个选项,用于基于列'C'的sign
创建运行长度ID分组,即,具有相同sign
的那些相邻元素将具有相同的分组'id',并且sign
中存在差异时,它会递增。然后,我们根据计数(n()
)的值创建特定的数字列,即3或4
library(dplyr)
library(data.table)
df %>%
mutate(C = B - lag(B)) %>%
group_by(grp = rleid(sign(C))) %>%
mutate(newC3 = if(n() ==3 && all(C < 0)) C else NA,newC4 = if(n() == 4 && all(C < 0) C else NA)
要使其自动化,pivot_wider
的一个选项是在用rleid
创建分组ID并替换非{{1 }}。这样,我们只将负值块放在单独的列中
NA
-输出
library(tidyr)
library(stringr)
df %>%
mutate(C = B - lag(B)) %>%
mutate(grp = str_c('C',rleid(sign(C))),C1 = case_when(C >=0 ~ NA_real_,TRUE ~ C)) %>%
pivot_wider(names_from = grp,values_from = C1)%>%
select(where(~ sum(!is.na(.)) > 0))
注意:列名'C2','C4','C7'基于使用# A tibble: 20 x 6
# A B C C2 C4 C7
# <int> <dbl> <dbl> <dbl> <dbl> <dbl>
# 1 1 2 NA NA NA NA
# 2 2 1.8 -0.200 -0.200 NA NA
# 3 3 1.6 -0.200 -0.200 NA NA
# 4 4 1.8 0.200 NA NA NA
# 5 5 4 2.2 NA NA NA
# 6 6 6 2 NA NA NA
# 7 7 8 2 NA NA NA
# 8 8 10 2 NA NA NA
# 9 9 12 2 NA NA NA
#10 10 10 -2 NA -2 NA
#11 11 8 -2 NA -2 NA
#12 12 6 -2 NA -2 NA
#13 13 13 7 NA NA NA
#14 14 14 1 NA NA NA
#15 15 15 1 NA NA NA
#16 16 16 1 NA NA NA
#17 17 16 0 NA NA NA
#18 18 15 -1 NA NA -1
#19 19 14 -1 NA NA -1
#20 20 13 -1 NA NA -1
创建的ID。如果我们想重命名,则可以使用rleid
或rename_with
rename_at