根据因子级别删除行

Max*_*Max 4 r subset r-factor data.table

我有一个df格式为"long" 的data.frame .

df <- data.frame(site = rep(c("A","B","C"), 1, 7),
                 time = c(11,11,11,22,22,22,33),
                 value = ceiling(rnorm(7)*10))
df <- df[order(df$site), ]

df
  site time value
1    A   11    12
2    A   22   -24
3    A   33   -30
4    B   11     3
5    B   22    16
6    C   11     3
7    C   22     9
Run Code Online (Sandbox Code Playgroud)

如何删除df$time每个级别不存在唯一元素的行df$site

在这种情况下,我想删除df[3,],因为df$time时间戳33仅存在于站点A而不存在于站点B和站点C.

期望的输出:

df.trimmed
  site time value
1    A   11    12
2    A   22   -24
4    B   11     3
5    B   22    16
6    C   11     3
7    C   22     9
Run Code Online (Sandbox Code Playgroud)

data.frame容易有800k行和200k个唯一时间戳.我不想使用循环,但我不知道怎么用量化的功能,如apply()lapply()针对这种情况.

Ben*_*nes 5

这是使用该data.table软件包的另一种可能的解决方案:

unTime <- unique(df$time)

library(data.table)

DT <- data.table(df, key = "site")

(notInAll <- unique(DT[, list(ans = which(!unTime %in% time)), by = key(DT)]$ans))
# [1] 3

DT[time %in% unTime[-notInAll]]

#      site time value
# [1,]    A   11     3
# [2,]    A   22    11
# [3,]    B   11    -6
# [4,]    B   22    -2
# [5,]    C   11   -19
# [6,]    C   22   -14
Run Code Online (Sandbox Code Playgroud)

来自Matthew
Nice的编辑.或者更直接的方式:

DT = as.data.table(df)
tt = DT[,length(unique(site)),by=time]
tt
   time V1
1:   11  3
2:   22  3
3:   33  1

tt = tt[V1==max(V1)]      # See * below
tt
   time V1
1:   11  3
2:   22  3

DT[time %in% tt$time]
   site time value
1:    A   11     7
2:    A   22    -2
3:    B   11     8
4:    B   22   -10
5:    C   11     3
6:    C   22     1
Run Code Online (Sandbox Code Playgroud)

如果所有站点都没有时间,当最终结果为空时(如Ben在评论中指出的那样),*上面标记的步骤可以是:

tt = tt[V1==length(unique(DT$site))]
Run Code Online (Sandbox Code Playgroud)