这是我先前问的R问题的扩展:How to select rows with certain values within a group in R
在这个问题上,我获得了很大的帮助,但是现在情况变得更加复杂了,我希望收到如何处理此问题的建议。
我的数据如下:
dd <- read.table(text="
event.timeline.ys ID year group outcome
1 2 800033 2008 A 3
2 1 800033 2009 A 3
3 0 800033 2010 A NA
4 -1 800033 2011 A 2
5 -2 800033 2012 A 1
15 0 800076 2008 B 2
16 -1 800076 2009 B NA
17 5 800100 2014 C 4
18 4 800100 2015 C 4
19 2 800100 2017 C 4
20 1 800100 2018 C 3
30 0 800125 2008 A 2
31 -1 800125 2009 A 1
32 -2 800125 2010 A NA
33 2 800031 2008 A 3
34 1 800031 2009 A 3
35 0 800031 2010 A NA
36 -1 800031 2011 A NA
37 -2 800031 2012 A 1", header=TRUE)
我只想选择组(ID)中的特殊行。这些行应根据以下过程选择:
如果可能的话,我想为每个参与者在event.timeline.ys上保留正值(例如,ID组中event.timeline.ys> = 0的最后一行),其中结果变量不是NA,但具有有效值(例如,对于ID == 800033,这将是第2行)。
此外,我想在第一行中为每个参与者在event.timeline.ys上保留负值(即,ID组中event.timeline.ys <0的第一行),其中结果变量不是NA(例如,对于ID == 800033,这将是第4行)。
在id == 800076的特殊情况下,当event.timeline.ys <0时,结果变量上没有任何非NA值,我仍然想保留event.timeline.ys中的第一行<0。
ID = 800100的人的event.timeline.ys上没有任何负值。在这种情况下,我只想保留event.timeline.ys> = 0的最后一行。
所有其他行均应删除。最终的数据帧如下所示:
event.timeline.ys ID year group outcome
2 1 800033 2009 A 3
4 -1 800033 2011 A 2
15 0 800076 2008 B 2
16 -1 800076 2009 B NA
20 1 800100 2018 C 3
30 0 800125 2008 A 2
31 -1 800125 2009 A 1
34 1 800031 2009 A 3
37 -2 800031 2012 A 1
我非常感谢有关如何解决此问题的建议。我已经尝试过了:
dd %>%
group_by(ID) %>%
filter(row_number() == last(which(event.timeline.ys >= 0 & outcome >= 0)) |
row_number() == first(which(event.timeline.ys < 0 & outcome >= 0)))
但是,我然后不幸地丢失了第16行(对于ID == 800076)。
非常感谢!
答案 0 :(得分:1)
这是使用dplyr
和wrapr
的管道%.>%
的解决方案。
我要添加outcome_na
并按其排列以符合“没有任何非NA值”的条件。
library(dplyr)
library(wrapr)
dd %>%
group_by(ID) %>%
mutate(outcome_na = !is.na(outcome)) %.>%
bind_rows(
filter(., event.timeline.ys >= 0) %>% arrange(outcome_na, year) %>% slice(n()),
filter(., event.timeline.ys < 0) %>% arrange(desc(outcome_na), year) %>% slice(1)
) %>%
arrange(ID) %>%
select(-outcome_na)
答案 1 :(得分:1)
使用dplyr
:
dd %>%
group_by(ID, event.timeline.ys>=0) %>%
arrange(ID, event.timeline.ys>=0, abs(event.timeline.ys)) %>%
filter(!is.na(outcome) | n()==1) %>%
filter(row_number()==1) %>%
ungroup() %>%
select(-one_of('event.timeline.ys >= 0'))
输出:
event.timeline.ys ID year group outcome
<int> <int> <int> <fct> <int>
1 -1 800033 2011 A 2
2 1 800033 2009 A 3
3 -1 800076 2009 B NA
4 0 800076 2008 B 2
5 1 800100 2018 C 3
6 -1 800125 2009 A 1
7 0 800125 2008 A 2
答案 2 :(得分:1)
只需使用data.table
与我先前的答案保持一致,我们就可以使用ifelse
条件选择行
library(data.table)
setDT(dd)
dd[, .SD[na.omit(c(ifelse(any(event.timeline.ys >= 0 & !is.na(outcome)),
last(which(event.timeline.ys >= 0 & !is.na(outcome))),
last(which(event.timeline.ys >= 0))),
ifelse(any(event.timeline.ys < 0 & !is.na(outcome)),
first(which(event.timeline.ys < 0 & !is.na(outcome))),
first(which(event.timeline.ys < 0)))))],
by=ID]
ID event.timeline.ys year group outcome
1: 800033 1 2009 A 3
2: 800033 -1 2011 A 2
3: 800076 0 2008 B 2
4: 800076 -1 2009 B NA
5: 800100 1 2018 C 3
6: 800125 0 2008 A 2
7: 800125 -1 2009 A 1
8: 800031 1 2009 A 3
9: 800031 -2 2012 A 1