使用R从数据框中提取数据并将数据存储在未知数量的新列中

问题描述

我的数据框如下:

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。如果我们想重命名,则可以使用rleidrename_with

完成。
rename_at