我希望在数据框中的行被子集化,条件是特定的值序列出现在一行中。例如,如果在变量之一中存在模式2 | 4 | 5一个接一个的行,将保留这三行,然后继续搜索,直到找到另一行并找到另外2行。 4 | 5.最终,我想每2个组中使用group_by()。 4 | 5,并在另一列中取相应值的平均值。
我尝试使用各种滞后命令,但无法使其正常工作。理想情况下,解决方案是使用dplyr。
给出下表
# A tibble: 24 x 2
information.content scale_degree
<dbl> <dbl>
1 4.95 0
2 2.98 2
3 2.13 4
4 2.46 2
5 2.49 4
6 1.75 5
7 1.95 7
8 2.54 5
9 0.969 4
10 1.45 2
11 2.10 4
12 2.37 2
13 2.07 4
14 1.29 5
15 1.43 7
16 4.05 7
17 2.05 5
18 0.740 4
19 1.07 2
20 1.92 0
21 2.54 2
22 1.72 4
23 1.69 2
24 1.85 0
structure(list(information.content = c(4.951615, 2.9770234, 2.1338997,
2.4575028, 2.4881902, 1.7465432, 1.9471669, 2.5410578, 0.96890986,
1.4460193, 2.0989947, 2.3660812, 2.0733728, 1.2867087, 1.4285704,
4.048128, 2.0472896, 0.74006027, 1.0694636, 1.9193107, 2.5353878,
1.721423, 1.6873852, 1.8456767), scale_degree = c(0, 2, 4, 2,
4, 5, 7, 5, 4, 2, 4, 2, 4, 5, 7, 7, 5, 4, 2, 0, 2, 4, 2, 0)), row.names = c(NA,
-24L), class = c("tbl_df", "tbl", "data.frame"))
我希望得到以下结果(会知道如何在没有问题的情况下进行分组和平均)
# A tibble: 6 x 3
information.content scale_degree instance
<dbl> <dbl> <dbl>
1 2.46 2 1
2 2.49 4 1
3 1.75 5 1
4 2.37 2 2
5 2.07 4 2
6 1.29 5 2
structure(list(information.content = c(2.4575028, 2.4881902,
1.7465432, 2.3660812, 2.0733728, 1.2867087), scale_degree = c(2,
4, 5, 2, 4, 5), instance = c(1, 1, 1, 2, 2, 2)), class = c("spec_tbl_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -6L), spec = structure(list(
cols = list(information.content = structure(list(), class = c("collector_double",
"collector")), scale_degree = structure(list(), class = c("collector_double",
"collector")), instance = structure(list(), class = c("collector_double",
"collector"))), default = structure(list(), class = c("collector_guess",
"collector")), skip = 1), class = "col_spec"))
答案 0 :(得分:2)
通过dplyr
的想法可能是利用lead
函数,即
library(dplyr)
df %>%
mutate(new = cumsum(ifelse(scale_degree == 2 &
lead(scale_degree, n = 1) == 4 &
lead(scale_degree, n = 2) == 5, 1, 0))) %>%
filter(new != 0) %>%
group_by(new) %>%
slice(1L:3L)
给出,
# A tibble: 6 x 3 # Groups: new [2] information.content scale_degree new <dbl> <dbl> <dbl> 1 2.46 2 1 2 2.49 4 1 3 1.75 5 1 4 2.37 2 2 5 2.07 4 2 6 1.29 5 2
答案 1 :(得分:2)
另一种dplyr
可能是:
df %>%
mutate(flag = row_number() %in% grepRaw("245",
paste0(scale_degree, collapse = ""),
all = TRUE,
fixed = TRUE)) %>%
group_by(flag = cumsum(flag)) %>%
filter(flag != 0) %>%
slice(1:3)
information.content scale_degree flag
<dbl> <dbl> <int>
1 2.46 2 1
2 2.49 4 1
3 1.75 5 1
4 2.37 2 2
5 2.07 4 2
6 1.29 5 2
注意:
如果“ scale_degree”的值介于0到9之间,它将起作用。
“ scale_degree”可能具有任何值的可能性:
df %>%
mutate(flag = row_number() %in% ((grepRaw("2,4,5",
paste0(c(0, scale_degree, 0), collapse = ","),
all = TRUE,
fixed = TRUE) - 1) / 2)) %>%
group_by(flag = cumsum(flag)) %>%
filter(flag != 0) %>%
slice(1:3)
答案 2 :(得分:1)
这是使用dplyr
软件包的一种可能的解决方案(可能不是最优雅的方法):
library(dplyr)
df %>%
filter((scale_degree == 2 & lead(scale_degree) == 4 & lead(scale_degree, 2) == 5) |
(scale_degree == 4 & lag(scale_degree) == 2 & lead(scale_degree) == 5) |
(scale_degree == 5 & lag(scale_degree) == 4 & lag(scale_degree, 2) == 2)) %>%
mutate(instance = cumsum(scale_degree == 2))
# A tibble: 6 x 3
information.content scale_degree instance
<dbl> <dbl> <int>
1 2.46 2 1
2 2.49 4 1
3 1.75 5 1
4 2.37 2 2
5 2.07 4 2
6 1.29 5 2