如何解决根据其他列 UserID 识别数据序列更改的情况
我正在处理一个数据框 df
,如下所示:
输入:
TUserId SUID mid_sum final_sum
115 201 2 7
115 309 1 8
115 404 1 9
209 245 2 10
209 398 2 10
209 510 2 10
209 602 1 10
371 111 2 11
371 115 1 11
371 123 3 11
371 124 2 11
1- 我的数据以 wide
格式排列,其中每一行都有一个唯一的学生 ID,显示为 SUID
。
2- 多个学生可以有相同的老师,因此多行的公共老师 ID 显示为 TUserId
。
3- 数据包括学生期中成绩和学生期末成绩。
4- 我很想知道是否有老师在期中给学生类似的分数(如 mid_sum
所示)在期末考试中给出不一致的分数(如 {{ 所示) 1}}。如果在数据中发现这种不一致,我想添加一个列final_sum
来记录这个Status
。
要求:
a- 为此,我的规则是,如果 inconsistency
和 mid_sum
按升序排序,就像我在此示例数据框 final_sum
中所做的那样。我想确定升序在这些列 df
和 mid_sum
中的任何一个中中断的情况。
b- 如果数据没有排序,可以做吗?
示例 1:
例如,对于 final_sum
,SUID = 309
是前一个 mid_sum
的递减。所以它应该被标记为mid_sum
。只有被同一位老师 inconsistent
评分的学生才会发生这种情况,在本例中为 TUserId
。
示例 2:
同样,对于 115
,SUID = 602
是前一个 mid_sum
的递减。所以它应该被标记为mid_sum
。同样,它是为同一个老师 inconsistent
为了进一步详细说明,我想要这样的输出:
输出:
TUserId = 209
数据导入dput()
数据框的 TUserId SUID mid_sum final_sum Status
115 201 2 7 consistent
115 309 1 8 inconsistent
115 404 1 9 consistent
209 245 2 10 consistent
209 398 2 10 consistent
209 510 2 10 consistent
209 602 1 10 inconsistent
371 111 2 11 consistent
371 115 1 11 inconsistent
371 123 3 11 consistent
371 124 2 11 inconsistent
如下:
dput()
我在 SO 上寻找了类似的问题并找到了这个 R - identify consecutive sequences,但它似乎并没有帮助我解决我的问题。 另一个相关的帖子是 Determine when a sequence of numbers has been broken in R,但同样,它对我的情况没有帮助。
关于如何解决这个问题的任何建议将不胜感激。
谢谢!
解决方法
这是我们测试滞后差异符号的一种相当简单的方法。如果 mid_sum 差值符号与 final_sum 差值符号相同,则它们是“一致的”。
library(dplyr)
df %>%
arrange(TUserId,final_sum) %>%
group_by(TUserId) %>%
mutate(
Status = if_else(
sign(final_sum + 0.1 - lag(final_sum,default = 0)) == sign(mid_sum + 0.1 - lag(mid_sum,default = 0)),"consisent","inconsistent"
)
)
# # A tibble: 11 x 5
# # Groups: TUserId [3]
# TUserId SUID mid_sum final_sum Status
# <int> <int> <int> <int> <chr>
# 1 115 201 2 7 consisent
# 2 115 309 1 8 inconsistent
# 3 115 404 1 9 consisent
# 4 209 245 2 10 consisent
# 5 209 398 2 10 consisent
# 6 209 510 2 10 consisent
# 7 209 602 1 10 inconsistent
# 8 371 111 2 11 consisent
# 9 371 115 1 11 inconsistent
# 10 371 123 3 11 consisent
# 11 371 124 2 11 inconsistent
+ .1
用于将分数保持相同的行作为正号计数。
也许 accumulate
系列函数就是为这些情况设计的。在此处使用 accumulate2
-
- 作为第一个参数,我通过
mid_sum
- 第二个参数是滞后值,即
lag(mid_sum)
,默认值是除NA
之外的任何值和它可能采用的实际值。我认为0
是安全的 -
.init
提供任何值。我只选择了c
。 - 如果第一个参数
(..2)
[..1 是累积值而不是第一个参数] 小于..3
即第二个参数,则返回inconsistent
elseconsistent
。立> - 现在,由于提供了
.init
,结果将比提供的值大一个值,因此删除了它的第一个值[-1]
df <- structure(list(
TUserId = c(115L,115L,209L,371L,371L),SUID = c(201L,309L,404L,245L,398L,510L,602L,111L,123L,124L),mid_sum = c(2L,1L,2L,3L,2L),final_sum = c(7L,8L,9L,10L,11L,11L)),class = "data.frame",row.names = c(NA,-11L))
library(tidyverse)
df %>%
arrange(TUserId,final_sum) %>%
group_by(TUserId) %>%
mutate(status = unlist(accumulate2(mid_sum,lag(mid_sum,default = 0),.init = 'c',~ if(..2 < ..3) 'inconsistent' else 'consistent')[-1]))
#> # A tibble: 11 x 5
#> # Groups: TUserId [3]
#> TUserId SUID mid_sum final_sum status
#> <int> <int> <int> <int> <chr>
#> 1 115 201 2 7 consistent
#> 2 115 309 1 8 inconsistent
#> 3 115 404 1 9 consistent
#> 4 209 245 2 10 consistent
#> 5 209 398 2 10 consistent
#> 6 209 510 2 10 consistent
#> 7 209 602 1 10 inconsistent
#> 8 371 111 2 11 consistent
#> 9 371 115 1 11 inconsistent
#> 10 371 123 3 11 consistent
#> 11 371 124 2 11 inconsistent
由 reprex package (v2.0.0) 于 2021 年 6 月 15 日创建
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。