我有数据集,其中每行代表个人进行的新测试。它有四个变量。
1)考生的ID:
id <- c(1, 1, 1, 2, 2)
2)个人参加考试的日期:
dates <- as.Date(c("2007-06-22", "2008-06-21", "2009-06-22", "2008-06-21", "2009-06-22"))
3)他们在测试中收到的分数:
scores <- c(0, 12, 12, 1, 3)
4)在该时间点之前,该得分是否是个人的最佳得分。
improvement <- c("No", "Yes", "No", "No", "Yes")
所以数据集是:
df <- data.frame(id, dates, scores, improvement)
id dates scores improvement
1 1 2007-06-22 0 No
2 1 2008-06-21 12 Yes
3 1 2009-06-22 12 No
4 2 2008-06-21 1 No
5 2 2009-06-22 3 Yes
我遇到了一个问题。得分为12是最高的。因此,如果有人获得12分,就没有更多的改进空间了。你知道我怎么能做到这一点,当有人得到一个12,在任何后续的行上他们得到NA改善?
即,
id dates scores improvement
1 1 2007-06-22 0 No
2 1 2008-06-21 12 Yes
3 1 2009-06-22 12 NA
4 2 2008-06-21 1 No
5 2 2009-06-22 3 Yes
答案 0 :(得分:3)
如何做到这一点:我们使用dplyr
按id
进行分组,然后对每个id
我们检查是否有任何分数等于12.如果是,那么我们将替换每个值在第一个得分为12的实例之后的后续行中improvement
NA
。
library(dplyr)
df %>% group_by(id) %>% arrange(id, dates) %>%
mutate(improvement = replace(improvement, if(any(scores==12)) (min(which(scores==12))+1):n(), NA))
id dates scores improvement <dbl> <date> <dbl> <fctr> 1 1 2007-06-22 0 No 2 1 2008-06-21 12 Yes 3 1 2009-06-22 12 NA 4 2 2008-06-21 1 No 5 2 2009-06-22 3 Yes
答案 1 :(得分:1)
也可以使用基础包完成操作。虽然它有点乱,但它为那些不熟悉parser.add_argument('--read', dest='book', help='book to read')
parser.add_argument('page', nargs='?', default=1, type=int, help='page number')
包等的人创造了机会。这是代码,我在代码中解释了我的逻辑:
dplyr
答案 2 :(得分:1)
以下是使用data.table
的选项。我们转换了&#39; data.frame&#39;到&#39; data.table&#39; (setDT(df)
),按&#39; id&#39;,order
分组&#39; id&#39;和&#39;日期&#39;,获取最高分数的逻辑索引(scores == max(scores)
),找到累积总和(cumsum(...)
),将其转换为逻辑vector
({{ 1}})并获取行索引(>1
)。在.I
中指定行索引,并在&#39;改进&#39;中分配(i
)元素。对应于:=
NA
如果最大值不相邻,我们可以library(data.table)
setDT(df)[df[order(id, dates), .I[cumsum(scores == max(scores))>1],
by = id]$V1, improvement := NA]
df
# id dates scores improvement
#1: 1 2007-06-22 0 No
#2: 1 2008-06-21 12 Yes
#3: 1 2009-06-22 12 NA
#4: 2 2008-06-21 1 No
#5: 2 2009-06-22 3 Yes
得分&#39;以及其他选择
order
对上述内容的略微改进是通过创建对象
来调用setDT(df1)[df1[order(id, dates), .I[cumsum(scores == max(scores))>1 &
scores ==max(scores)], by = id]$V1, improvement := NA]
df1
# id dates scores improvement
#1: 1 2007-06-22 0 No
#2: 1 2008-06-21 12 Yes
#3: 1 2009-06-22 5 No
#4: 1 2010-06-21 12 NA
#5: 2 2008-06-21 1 No
#6: 2 2009-06-22 3 Yes
一次
scores==max(scores)
setDT(df1)[df1[order(id, dates), {mx <- scores == max(scores)
.I[cumsum(mx)>1 & mx]},
by = id]$V1, improvement := NA]