我正在尝试重新格式化纵向数据一段时间来进行事件分析。在下面的示例数据中,我只想找到每个ID的结果为“0”的最早一周。
我遇到的特有的问题是如何处理那些没有转换为0的病人,他们要么拥有所有的1,要么有2。在示例数据中,患者J拥有所有的1。
#Sample data
have<-data.frame(patient=rep(LETTERS[1:10], each=9),
week=rep(0:8,times=10),
result=c(1,0,2,rep(0,6),1,1,2,1,rep(0,5),1,1,rep(0,7),1,rep(0,8),
1,1,1,1,2,1,0,0,0,1,1,1,rep(0,6),1,2,1,rep(0,6),1,2,rep(0,7),
1,rep(0,8),rep(1,9)))
patient week result
A 0 1
A 1 0
A 2 2
A 3 0
A 4 0
A 5 0
A 6 0
A 7 0
A 8 0
B 0 1
B 1 0
... .....
J 6 1
J 7 1
J 8 1我能够用以下代码完成这个相对简单的过程:
want<-aggregate(have$week, by=list(have$patient,have$result), min) want<-want[which(want[2]==0),]
但是要知道,如果某人没有转换为0,它就会将他们排除在外(在本例中,病人J被排除在外)。相反,J应该在第二列中有一个1,在第三列中有一个8。相反,它当然被省略了。
print(want)
Group.1 Group.2 x
A 0 1
B 0 4
C 0 2
D 0 1
E 0 6
F 0 3
G 0 3
H 0 2
I 0 1
#But also need
J 1 8根据这里发布的指导方针,我确实努力解决了这个问题,能够得到我所需要的非常笨拙的东西:
mins<-aggregate(have$week, by=list(have$patient,have$result), min)
maxs<-aggregate(have$week, by=list(have$patient,have$result), max)
want<-rbind(mins[which(mins[2]==0),],maxs[which(maxs[2]==1&maxs[3]==8),])这将返回正确的所需数据集,但由于我使用其他数据集(即,由于必须手动输入maxsp[3]==8,所以时间框架不同的数据集),编码非常糟糕且不可持续。
是否有更优雅或更系统的方法来处理这个数据操作问题?
发布于 2020-04-11 12:13:16
我们可以编写一个函数来从组中选择一行。
select_row <- function(result, week) {
if(any(result == 0)) which.max(result == 0) else which.max(week)
}如果存在该函数,则返回前0值的索引,否则返回week最大值的索引。
并将其应用于所有团体。
library(dplyr)
have %>% group_by(patient) %>% slice(select_row(result, week))
# patient week result
# <fct> <int> <dbl>
# 1 A 1 0
# 2 B 4 0
# 3 C 2 0
# 4 D 1 0
# 5 E 6 0
# 6 F 3 0
# 7 G 3 0
# 8 H 2 0
# 9 I 1 0
#10 J 8 1https://stackoverflow.com/questions/61156319
复制相似问题