【问题标题】:Selecting only those levels of a factor which appear in each level of other factor仅选择出现在其他因子的每个级别中的因子的那些级别
【发布时间】:2018-02-25 08:00:35
【问题描述】:

我想只选择出现在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")

在这里我知道外观的模式。我正在寻找更通用的解决方案。

【问题讨论】:

  • Trt 的所有级别均未出现在Loc 中。也许定义Trtpaste0 之一应该有"L" 而不是"T" 的两倍?

标签: r dplyr data.table filtering data-manipulation


【解决方案1】:

您实际上是在尝试找出在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)

【讨论】:

  • 感谢@Ken S. 的回答。我猜你在答案中错过了一些代码。 intersectTrtvals 是什么?
【解决方案2】:

这是基于 R 的另一个想法。我们基于 Loc 拆分 Trt 并使用 Reduceintersect 来查找所有常见元素。我们使用这些元素来索引原始数据框,即

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

【讨论】:

    【解决方案3】:

    使用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
    

    每个TrtLoc的唯一级别数为

    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"]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-10-13
      • 1970-01-01
      • 2019-10-13
      • 2014-04-12
      • 2015-02-24
      • 2011-10-04
      • 1970-01-01
      相关资源
      最近更新 更多