我有一个数据框,每个ID有多个观察点,如下所示:
修改:更新数据框
df <- data.frame(ID=c(1,1,1,2,2,3,3,3,4), V1=c("A","B","C","A","A","B","B","C","A"),
V2=rnorm(9))
> df
ID V1 V2
1 1 A 1.57707547
2 1 B -0.76022296
3 1 C -0.82693346
4 2 A 1.80888747
5 2 A -0.53173950
6 3 B -1.18705727
7 3 B 0.04325324
8 3 C -0.33361802
9 4 A -0.02358198
现在我想以下列方式选择每个ID的所有行:
在我的例子中,我想要这个:
ID V1 V2
1 1 A 1.57707547
2 2 A 1.80888747
3 2 A -0.53173950
4 3 B -1.18705727
5 3 B 0.04325324
6 4 A -0.02358198
如果适用,我还希望看到dplyr
解决方案。
答案 0 :(得分:3)
以下是dplyr
的一个选项。我们按照ID&#39;分组列,filter
具有&#39; A&#39;的行或者&#39; B&#39;行,再做filter
来检查&#39; V1&#39;中的唯一元素的数量。 (n_distinct(V1)
)。如果它大于1,则元素是&#39; A&#39;我们选择它(n_distinct(V1)>1 & V1=='A'
)或我们选择所有独特元素的长度为1.
library(dplyr)
df %>%
group_by(ID) %>%
filter(V1 %in% c('A', 'B'))%>%
filter(n_distinct(V1)>1 & V1=='A'|n_distinct(V1)==1)
# ID V1 V2
#1 1 A 1.57707547
#2 2 A 1.80888747
#3 2 A -0.53173950
#4 3 B -1.18705727
#5 3 B 0.04325324
#6 4 A -0.02358198
也许我们可以使用单个filter
来修改版本。我们检查&#39; V1&#39;中是否有独特元素的数量。大于1,如果没有元素是&#39; A&#39; (all(V1!='A')
)如果元素是&#39; B&#39;,我们选择该行,或者如果不同元素的数量大于1并且有一个&#39; A&#39;在其中的元素,选择该行或如果唯一元素的数量是1并且该元素是&#39; A&#39;或者&#39; B&#39;,选择行。
df %>%
group_by(ID) %>%
filter(n_distinct(V1)>1 & all(V1 !='A') & V1=='B'|n_distinct(V1)>1 &
V1=='A' |n_distinct(V1)==1 & V1 %in% c('A', 'B') )
# ID V1 V2
#1 1 A 1.57707547
#2 2 A 1.80888747
#3 2 A -0.53173950
#4 3 B -1.18705727
#5 3 B 0.04325324
#6 4 A -0.02358198
或者稍微紧凑一点(灵感来自@ MichaelChirico的帖子)。我们将&#39; ID&#39;和filter
分组为V1和&#39; A&#39;行或&#39; B&#39;没有任何&#39; A&#39;行。
df %>%
group_by(ID) %>%
filter(V1=='A'|V1=='B'&!any(V1=='A'))
# ID V1 V2
#1 1 A 1.57707547
#2 2 A 1.80888747
#3 2 A -0.53173950
#4 3 B -1.18705727
#5 3 B 0.04325324
#6 4 A -0.02358198
答案 1 :(得分:2)
在data.table
中,可以通过以下方式轻松完成:
library(data.table); setDT(df)
df[df[,.I[V1=="A"|(V1=="B"&!"A"%in%unique(V1))],by=ID]$V1]
内部df
调用选择索引(.I
),其中a)V1
为A
或b)V1
为B
A
V1
中没有其他ID
元素(即by
ID
); $V1
提取这些索引并将其传递回外部df
。
(我们提取V1
可能会让人感到困惑,因为原始表中有一列名为V1
,但我们提取的V1
不同;要看到这一点,请考虑这个替代方案我们在哪里命名结果变量:
df[df[,.(ind=.I[V1=="A"|(V1=="B"&!"A"%in%unique(V1))]),by=ID]$ind]
在这里,我们将索引变量命名为ind
,因此我们必须提取ind
而不是V1
)