将逻辑运算符与 %in% 和子集一起使用
Using logical operators with %in% and subset
我有一个按季度拆分的测试数据集:
> test
id quarter
1 7 Q1
2 7 Q1
3 5 Q1
4 8 Q1
5 3 Q1
6 6 Q1
7 10 Q1
8 3 Q2
9 10 Q2
10 8 Q2
11 2 Q2
12 7 Q2
13 6 Q2
14 6 Q3
15 9 Q3
16 6 Q3
17 4 Q3
18 9 Q3
19 2 Q3
20 5 Q4
21 8 Q4
22 10 Q4
23 7 Q4
24 1 Q4
25 8 Q4
subsets <-split(test, test$quarter, drop=TRUE)
for (i in 1:length(subsets)) {
assign(paste0("Q", i), as.data.frame(subsets[[i]]))
}
现在我的 objective 是找出 Q3
中不在 Q1
或 Q2
中的所有唯一 ID。使用 %in%
运算符我尝试:
Q1_ids <- unique(Q1$id)
Q2_ids <- unique(Q2$id)
Q3_ids <- subset(unique(Q3$id), !(unique(Q3$id) %in% Q1_ids | Q2_ids))
但随后我收到一个错误 operations are possible only for numeric, logical or complex types
。我可以按一个向量进行子集化,例如,如果我只使用 Q1_ids,但我不能使用逻辑运算符。使用 subset()
函数或其他方法解决此问题的解决方案是什么?
> dput(test)
structure(list(id = c(7, 7, 5, 8, 3, 6, 10, 3, 10, 8, 2, 7, 6,
6, 9, 6, 4, 9, 2, 5, 8, 10, 7, 1, 8), quarter = c("Q1", "Q1",
"Q1", "Q1", "Q1", "Q1", "Q1", "Q2", "Q2", "Q2", "Q2", "Q2", "Q2",
"Q3", "Q3", "Q3", "Q3", "Q3", "Q3", "Q4", "Q4", "Q4", "Q4", "Q4",
"Q4")), .Names = c("id", "quarter"), row.names = c(NA, -25L), class = "data.frame", index = structure(integer(0), "`__quarter`" = integer(0)))
Q3_ids <- unique(setdiff(Q3$id , union(Q2$id, Q1$id)))
您始终可以只编写一个函数来提取您要查找的元素,然后调用 map(或应用函数)将该函数应用于每个季度。这个特定的 tidyverse 解决方案将输出一个命名列表,其中包含每个季度所需的输出:
library(tidyverse)
get_distinct <- function(x, data) {
distinct_id <- data[data$quarter == x, 1] %>%
unique()
setdiff(distinct_id, data[!data$quarter == x, 1] %>%
unique())
}
quarters <- unique(test$quarter)
dat <- map(.x = quarters, .f = get_distinct, data = test) %>%
set_names(quarters)
我有一个按季度拆分的测试数据集:
> test
id quarter
1 7 Q1
2 7 Q1
3 5 Q1
4 8 Q1
5 3 Q1
6 6 Q1
7 10 Q1
8 3 Q2
9 10 Q2
10 8 Q2
11 2 Q2
12 7 Q2
13 6 Q2
14 6 Q3
15 9 Q3
16 6 Q3
17 4 Q3
18 9 Q3
19 2 Q3
20 5 Q4
21 8 Q4
22 10 Q4
23 7 Q4
24 1 Q4
25 8 Q4
subsets <-split(test, test$quarter, drop=TRUE)
for (i in 1:length(subsets)) {
assign(paste0("Q", i), as.data.frame(subsets[[i]]))
}
现在我的 objective 是找出 Q3
中不在 Q1
或 Q2
中的所有唯一 ID。使用 %in%
运算符我尝试:
Q1_ids <- unique(Q1$id)
Q2_ids <- unique(Q2$id)
Q3_ids <- subset(unique(Q3$id), !(unique(Q3$id) %in% Q1_ids | Q2_ids))
但随后我收到一个错误 operations are possible only for numeric, logical or complex types
。我可以按一个向量进行子集化,例如,如果我只使用 Q1_ids,但我不能使用逻辑运算符。使用 subset()
函数或其他方法解决此问题的解决方案是什么?
> dput(test)
structure(list(id = c(7, 7, 5, 8, 3, 6, 10, 3, 10, 8, 2, 7, 6,
6, 9, 6, 4, 9, 2, 5, 8, 10, 7, 1, 8), quarter = c("Q1", "Q1",
"Q1", "Q1", "Q1", "Q1", "Q1", "Q2", "Q2", "Q2", "Q2", "Q2", "Q2",
"Q3", "Q3", "Q3", "Q3", "Q3", "Q3", "Q4", "Q4", "Q4", "Q4", "Q4",
"Q4")), .Names = c("id", "quarter"), row.names = c(NA, -25L), class = "data.frame", index = structure(integer(0), "`__quarter`" = integer(0)))
Q3_ids <- unique(setdiff(Q3$id , union(Q2$id, Q1$id)))
您始终可以只编写一个函数来提取您要查找的元素,然后调用 map(或应用函数)将该函数应用于每个季度。这个特定的 tidyverse 解决方案将输出一个命名列表,其中包含每个季度所需的输出:
library(tidyverse)
get_distinct <- function(x, data) {
distinct_id <- data[data$quarter == x, 1] %>%
unique()
setdiff(distinct_id, data[!data$quarter == x, 1] %>%
unique())
}
quarters <- unique(test$quarter)
dat <- map(.x = quarters, .f = get_distinct, data = test) %>%
set_names(quarters)