我希望我能解释一下我的问题。我可以让R做我想做的事,但感觉非常笨拙,所以我正在寻找一种更好的方法来获得相同的结果。
我有一个看起来像这样的数据框(虽然如果它们更好用,我也会对其他结构开放。)
subject <- c(1,1,3,3)
day <- c(3, 20, 1, 14)
status <- c(1, 1, 1, 3)
df <- cbind(subject, day, status)
我想找到最有效的方式来查看,例如,如果主题1在第3天的状态为1(是),或者在第20天测试主体是否具有3以外的状态。到目前为止,我的尝试是功能但笨拙和丑陋。
has_event <- function(i, j, data) {
any(data[(data[, "subject"] == i) & (data[, "status"] != 3), "day"] == j)
}
has_event(1, 3, df) # evaluates to TRUE
has_event(1, 4, df) # evaluates to FALSE
我没有看到这种方法走得太远,因为逻辑只会变得更加复杂。我觉得我错过了一些非常简单的调用数据的方法。例如,如果我想查看特定日期有多少主题没有状态3,那么使用我的方法看起来就像这样:
length(unique(df[, "subject"],)) - length(which(df[, "status"] == 3 & df[, "day"] == 14))
这只是难以管理的。
总体目标是以一种我可以通过日期或主题轻松访问事物的方式格式化我的数据,但我现在正在挣扎着不确定要调查哪条途径。
答案 0 :(得分:3)
dplyr::filter()
如何,但请记住将矩阵转换为data.frame。只需逐个添加过滤条件。
df<-data.frame(df)
require(dplyr)
filter(df,status!=3,day==20)
subject day status
1 1 20 1
或使用data.table
require(data.table)
data.table(df)[status!=3][day==20]
实际上为10万个rec dplyr
计时更快,但对于这些简单的排序都很快:
df<-data.frame(subject=sample(1:5,100000,T),day=sample(1:20,100000,T),status=sample(1:10,100000,T))
> system.time(data.table(df)[status!=3][day==20])
user system elapsed
0.01 0.00 0.02
> system.time(filter(df,status!=3,day==20))
user system elapsed
0 0 0
答案 1 :(得分:2)
使用sqldf
包:
df <- data.frame(df)
require(sqldf)
sqldf("select * from df where status!=3 and day=20")
subject day status
1 1 20 1