提问人:wacekk 提问时间:7/17/2023 最后编辑:Markwacekk 更新时间:7/18/2023 访问量:37
data.frame 中的序列检测
Sequence detection in data.frame
问:
我有一个数据帧(tibble)。我正在寻找一种方法来检测数据中特定变量序列。reprex 中有 3 个变量,但可以有几十个。我展示了 70 行数据,可能有几十万行。我有一个序列来检测命名列表中的数据帧。在 reprex 中,有 2 个标记为 A 和 B 的序列,但实际上大约有 100 个,所以我选择了这种结构来存储它们。
数据:
library(tidyverse)
data1 <- structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70), x1 = c("z", "z", "z",
"z", "z", "z", "z", "y", "y", "y", "c", "c", "c", "c", "c", "c",
"c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c",
"a", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z", "z",
"z", "z", "y", "y", "y", "c", "c", "c", "c", "c", "c", "c", "c",
"c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "a", "z",
"z", "z"), x2 = c("z", "z", "z", "z", "z", "z", "z", "y", "y",
"y", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c",
"c", "c", "c", "c", "c", "c", "c", "a", "z", "z", "z", "z", "z",
"z", "z", "z", "z", "z", "z", "z", "z", "z", "y", "y", "y", "c",
"c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c",
"c", "c", "c", "c", "c", "a", "z", "z", "z"), x3 = c("c", "c",
"c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "z", "z", "z",
"z", "z", "z", "z", "z", "z", "z", "f", "f", "f", "f", "c", "c",
"c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c", "c",
"c", "c", "c", "c", "c", "c", "c", "c", "z", "z", "z", "z", "z",
"z", "z", "z", "z", "z", "f", "f", "f", "f", "c", "c", "c", "c",
"c", "c", "c")), row.names = c(NA, -70L), class = c("tbl_df",
"tbl", "data.frame"))
创建于 2023-07-17 使用 reprex v2.0.2
要检测的序列:
seqs <- list(A = structure(list(ID = c(1, 2, 3, 4, 5),
x1 = c("y", "y", "y", "c", "c"),
x2 = c("y", "y", "y", "c", "c"),
x3 = c("c", "c", "c", "c", "c")),
class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -5L)),
B = structure(list(ID = c(1, 2, 3, 4, 5, 6, 7, 8),
x1 = c("c", "c", "c", "c", "c", "c", "c", "a"),
x2 = c("c", "c", "c", "c", "c", "c", "c", "a"),
x3 = c("f", "f", "f", "f", "c", "c", "c", "c")),
class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -8L)))
创建于 2023-07-17 使用 reprex v2.0.2
我想得到这样的结果,在列中,我得到序列在哪一秒开始的信息。reprex 中搜索的序列由与我无关的其他序列分隔。重要的是,序列的检测是所有变量的序列检测(序列可能略有不同,只有一个变量的一个值)。我只需要找到序列的开头,因为它的持续时间是已知的(数据框的行数与序列的模式)。
ID x1 x2 x3 det_seq
<dbl> <chr> <chr> <chr> <chr>
1 1 z z c NA
2 2 z z c NA
3 3 z z c NA
4 4 z z c NA
5 5 z z c NA
6 6 z z c NA
7 7 z z c NA
8 8 y y c A
9 9 y y c NA
10 10 y y c NA
11 11 c c c NA
12 12 c c c NA
13 13 c c z NA
14 14 c c z NA
15 15 c c z NA
16 16 c c z NA
17 17 c c z NA
18 18 c c z NA
19 19 c c z NA
20 20 c c z NA
21 21 c c z NA
22 22 c c z NA
23 23 c c f B
24 24 c c f NA
25 25 c c f NA
26 26 c c f NA
27 27 c c c NA
28 28 c c c NA
29 29 c c c NA
30 30 a a c NA
31 31 z z c NA
32 32 z z c NA
33 33 z z c NA
34 34 z z c NA
35 35 z z c NA
36 36 z z c NA
37 37 z z c NA
38 38 z z c NA
39 39 z z c NA
40 40 z z c NA
41 41 z z c NA
42 42 z z c NA
43 43 z z c NA
44 44 z z c NA
45 45 y y c A
46 46 y y c NA
47 47 y y c NA
48 48 c c c NA
49 49 c c c NA
50 50 c c z NA
51 51 c c z NA
52 52 c c z NA
53 53 c c z NA
54 54 c c z NA
55 55 c c z NA
56 56 c c z NA
57 57 c c z NA
58 58 c c z NA
59 59 c c z NA
60 60 c c f B
61 61 c c f NA
62 62 c c f NA
63 63 c c f NA
64 64 c c c NA
65 65 c c c NA
66 66 c c c NA
67 67 a a c NA
68 68 z z c NA
69 69 z z c NA
70 70 z z c NA
答:
0赞
Mark
7/17/2023
#1
这里有一种方法:
data1 %>%
mutate(det_seq = map_chr(seq_along(1:nrow(data1)),
~ case_when(identical(data1[.x:(.x+4), 2:4], seqs$A[,2:4]) ~ "A",
identical(data1[.x:(.x+7), 2:4], seqs$B[,2:4]) ~ "B",
TRUE ~ "NA")))
更新:若要使其能够匹配任何大小的数据帧列表,请改用以下代码块:seqs
data1 %>%
mutate(det_seq = map_chr(seq_along(1:nrow(data1)),
\(x) first(names(seqs)[map_lgl(seqs,
\(s) identical(data1[x:(x+nrow(s)-1), 2:4], s[,2:4]))])))
评论
0赞
wacekk
7/18/2023
这就是我一直在寻找的。我只想自动输入序列的长度及其名称。我可能有大约 100 个序列。你可以从我的数据中获取长度和名称seqs %>% map(nrow) %>% flatten_int()
names(seqs)
0赞
wacekk
7/18/2023
一种解决方案是自动生成条件的代码(我正在使用包),但我更喜欢用作普通 r 代码的东西,以便它可以在循环或函数中使用,例如。stringi
cat(stri_join("identical(data1[.x:(.x+", seqs %>% map_int(nrow)-1, "), 2:4], seqs$", names(seqs), "[,2:4]) ~ \"", names(seqs), "\",\n"))
0赞
Mark
7/18/2023
@wacekk谁告诉你地图调用不能在函数中工作,那是在骗你。循环在 R 中很慢,但由于请求的复杂性,它们可能是必需的
0赞
Mark
7/18/2023
@wacekk更新!
1赞
wacekk
7/18/2023
谢谢你@Mark。这正是我一直在寻找的。
评论