仅选择出现在其他因素的每个水平中的那些水平的因素
Selecting only those levels of a factor which appear in each level of other factor
我只想select那些出现在Loc
每个级别的Trt
级别(通常出现在每个大型数据集的Loc
级别) .
Loc <- rep(paste0("L", 1:2), c(6, 4))
Trt <- c(rep(paste0("T", 1:3), times = 2), rep(paste0("T", 1:2), times = 2))
set.seed(12345)
Y <- c(rnorm(n=5, mean = 50, sd = 5), NA, rnorm(n=4, mean = 50, sd = 5))
df1 <- data.frame(Loc, Trt, Y)
df1
Loc Trt Y
1 L1 T1 52.92764
2 L1 T2 53.54733
3 L1 T3 49.45348
4 L1 T1 47.73251
5 L1 T2 53.02944
6 L1 T3 NA
7 L2 T1 40.91022
8 L2 T2 53.15049
9 L2 T1 48.61908
10 L2 T2 48.57920
需要输出
Loc Trt Y
L1 T1 52.92764
L1 T2 53.54733
L1 T1 47.73251
L1 T2 53.02944
L2 T1 40.91022
L2 T2 53.15049
L2 T1 48.61908
L2 T2 48.57920
这可以使用
来实现
library(dplyr)
df1 %>% filter(Trt != "T3")
这里我知道了外观的样式。我正在寻找更通用的解决方案。
您实质上是在尝试找出 df1$Loc
的每个级别中存在哪些 df1$Trt
值。 dplyr
中可能有一些我不知道的好方法。在基础 R
中你可以这样做:
dirty <- lapply( levels(df1$Loc), function(x) df1$Trt[df1$Loc == x])
clean <- do.call(intersect, dirty)
df1[df1$Trt %in% clean, ]
# Loc Trt Y
# 1 L1 T1 52.92764
# 2 L1 T2 53.54733
# 4 L1 T1 47.73251
# 5 L1 T2 53.02944
# 7 L2 T1 40.91022
# 8 L2 T2 53.15049
# 9 L2 T1 48.61908
# 10 L2 T2 48.57920
在最后一步中,您也可以坚持使用您的 dplyr
解决方案:
df1 %>% filter(Trt %in% clean)
这是另一种基于 R 的想法。我们根据 Loc
拆分 Trt
,并使用 Reduce
和 intersect
来查找所有公共元素。我们使用这些元素来索引原始数据框,即
i1 <- Reduce(intersect, split(df1$Trt, df1$Loc))
df1[df1$Trt %in% i1,]
这给出了,
Loc Trt Y
1 L1 T1 52.92764
2 L1 T2 53.54733
4 L1 T1 47.73251
5 L1 T2 53.02944
7 L2 T1 40.91022
8 L2 T2 53.15049
9 L2 T1 48.61908
10 L2 T2 48.57920
使用data.table
,一个可能的解决方案是
library(data.table)
setDT(df1)[df1[, uniqueN(Loc), by = Trt][V1 == df1[, uniqueN(Loc)]], on = "Trt"][, -"V1"]
Loc Trt Y
1: L1 T1 52.92764
2: L1 T1 47.73251
3: L2 T1 40.91022
4: L2 T1 48.61908
5: L1 T2 53.54733
6: L1 T2 53.02944
7: L2 T2 53.15049
8: L2 T2 48.57920
解释
Loc
的独特关卡总数为
df1[, uniqueN(Loc)]
[1] 2
每个Trt
中Loc
的唯一级别数是
df1[, uniqueN(Loc), by = Trt]
Trt V1
1: T1 2
2: T2 2
3: T3 1
包含Loc
所有关卡的Trt
关卡是
df1[, uniqueN(Loc), by = Trt][V1 == df1[, uniqueN(Loc)]]
Trt V1
1: T1 2
2: T2 2
现在,此权利与 df1
合并并从结果中删除了辅助列:
df1[df1[, uniqueN(Loc), by = Trt][V1 == df1[, uniqueN(Loc)]], on = "Trt"][, -"V1"]
我只想select那些出现在Loc
每个级别的Trt
级别(通常出现在每个大型数据集的Loc
级别) .
Loc <- rep(paste0("L", 1:2), c(6, 4))
Trt <- c(rep(paste0("T", 1:3), times = 2), rep(paste0("T", 1:2), times = 2))
set.seed(12345)
Y <- c(rnorm(n=5, mean = 50, sd = 5), NA, rnorm(n=4, mean = 50, sd = 5))
df1 <- data.frame(Loc, Trt, Y)
df1
Loc Trt Y
1 L1 T1 52.92764
2 L1 T2 53.54733
3 L1 T3 49.45348
4 L1 T1 47.73251
5 L1 T2 53.02944
6 L1 T3 NA
7 L2 T1 40.91022
8 L2 T2 53.15049
9 L2 T1 48.61908
10 L2 T2 48.57920
需要输出
Loc Trt Y
L1 T1 52.92764
L1 T2 53.54733
L1 T1 47.73251
L1 T2 53.02944
L2 T1 40.91022
L2 T2 53.15049
L2 T1 48.61908
L2 T2 48.57920
这可以使用
来实现 library(dplyr)
df1 %>% filter(Trt != "T3")
这里我知道了外观的样式。我正在寻找更通用的解决方案。
您实质上是在尝试找出 df1$Loc
的每个级别中存在哪些 df1$Trt
值。 dplyr
中可能有一些我不知道的好方法。在基础 R
中你可以这样做:
dirty <- lapply( levels(df1$Loc), function(x) df1$Trt[df1$Loc == x])
clean <- do.call(intersect, dirty)
df1[df1$Trt %in% clean, ]
# Loc Trt Y
# 1 L1 T1 52.92764
# 2 L1 T2 53.54733
# 4 L1 T1 47.73251
# 5 L1 T2 53.02944
# 7 L2 T1 40.91022
# 8 L2 T2 53.15049
# 9 L2 T1 48.61908
# 10 L2 T2 48.57920
在最后一步中,您也可以坚持使用您的 dplyr
解决方案:
df1 %>% filter(Trt %in% clean)
这是另一种基于 R 的想法。我们根据 Loc
拆分 Trt
,并使用 Reduce
和 intersect
来查找所有公共元素。我们使用这些元素来索引原始数据框,即
i1 <- Reduce(intersect, split(df1$Trt, df1$Loc))
df1[df1$Trt %in% i1,]
这给出了,
Loc Trt Y 1 L1 T1 52.92764 2 L1 T2 53.54733 4 L1 T1 47.73251 5 L1 T2 53.02944 7 L2 T1 40.91022 8 L2 T2 53.15049 9 L2 T1 48.61908 10 L2 T2 48.57920
使用data.table
,一个可能的解决方案是
library(data.table)
setDT(df1)[df1[, uniqueN(Loc), by = Trt][V1 == df1[, uniqueN(Loc)]], on = "Trt"][, -"V1"]
Loc Trt Y 1: L1 T1 52.92764 2: L1 T1 47.73251 3: L2 T1 40.91022 4: L2 T1 48.61908 5: L1 T2 53.54733 6: L1 T2 53.02944 7: L2 T2 53.15049 8: L2 T2 48.57920
解释
Loc
的独特关卡总数为
df1[, uniqueN(Loc)]
[1] 2
每个Trt
中Loc
的唯一级别数是
df1[, uniqueN(Loc), by = Trt]
Trt V1 1: T1 2 2: T2 2 3: T3 1
包含Loc
所有关卡的Trt
关卡是
df1[, uniqueN(Loc), by = Trt][V1 == df1[, uniqueN(Loc)]]
Trt V1 1: T1 2 2: T2 2
现在,此权利与 df1
合并并从结果中删除了辅助列:
df1[df1[, uniqueN(Loc), by = Trt][V1 == df1[, uniqueN(Loc)]], on = "Trt"][, -"V1"]