使用 R 从数据框中提取数据并将数据存储在未知数量的新列中
Using R to extract data from a dataframe and store data in unknown number of new columns
我有一个数据框如下:
library(dplyr)
df <- data.frame(A=1:20,
B=c(2,1.8,1.6,1.8,4,6,8,10,12,10,8,6,13,14,15,16,16.5,15,14,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
并且我想提取出连续有3个或更多的负值序列并放在单独的列中。因此,例如,将(col C)第 10、11、12 行的值放在新列中,将第 17、18、19、20 行的值放在另一个新列中。这个数据框很大,所以我不知道我会有多少新列。任何帮助,将不胜感激。谢谢
这里有一个带有 rleid
的选项,可以根据列 'C' 的 sign
创建一个 run-length-id 分组,即那些具有相同 [=15= 的相邻元素] 将具有相同的分组 '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 并替换值后从 'long' 重塑为 'wide' 格式不否定 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))
-输出
# 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
注意:列名称 'C2'、'C4'、'C7' 基于使用 rleid
创建的 ID。如果我们想重命名,那么可以用 rename_with
或 rename_at
来完成
...
%>%
rename_at(vars(matches('^C\d+')), ~ str_c('C', seq_along(.)))
我有一个数据框如下:
library(dplyr)
df <- data.frame(A=1:20,
B=c(2,1.8,1.6,1.8,4,6,8,10,12,10,8,6,13,14,15,16,16.5,15,14,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
并且我想提取出连续有3个或更多的负值序列并放在单独的列中。因此,例如,将(col C)第 10、11、12 行的值放在新列中,将第 17、18、19、20 行的值放在另一个新列中。这个数据框很大,所以我不知道我会有多少新列。任何帮助,将不胜感激。谢谢
这里有一个带有 rleid
的选项,可以根据列 'C' 的 sign
创建一个 run-length-id 分组,即那些具有相同 [=15= 的相邻元素] 将具有相同的分组 '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 并替换值后从 'long' 重塑为 'wide' 格式不否定 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))
-输出
# 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
注意:列名称 'C2'、'C4'、'C7' 基于使用 rleid
创建的 ID。如果我们想重命名,那么可以用 rename_with
或 rename_at
...
%>%
rename_at(vars(matches('^C\d+')), ~ str_c('C', seq_along(.)))