识别数据序列根据其他列 UserID 发生变化的情况
Identify cases where data sequence changes based on other column UserIDs
我正在处理一个数据框 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
所示,在期中考试中给学生相似分数的老师在期末考试中给出的分数不一致,如final_sum
。如果在数据中发现这种不一致,我想添加一列Status
来记录这个inconsistency
。
要求:
a- 为此,我的规则是如果 mid_sum
和 final_sum
按升序排序,就像我在这个示例数据框 df
中所做的那样。我想确定在 mid_sum
和 final_sum
.
这些列中的任何一个中升序中断的情况
b- 如果数据没有排序,能做到吗?
示例 1:
例如,对于SUID = 309
,mid_sum
是从前面的mid_sum
减去的。所以它应该被标记为inconsistent
。它应该只发生在被同一个老师 TUserId
打分的学生身上,在这种情况下是 115
.
示例 2:
同样,对于SUID = 602
,mid_sum
是从前面的mid_sum
减去的。所以它应该被标记为inconsistent
。同样,这是给同一个老师的TUserId = 209
为了进一步详细说明,我想要这样的输出:
输出:
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()
数据框的dput()
如下:
dput(df)
structure(list(
TUserId = c(115L, 115L, 115L, 209L, 209L, 209L, 209L, 371L, 371L, 371L, 371L),
SUID = c(201L, 309L, 404L, 245L, 398L, 510L, 602L, 111L, 115L, 123L, 124L),
mid_sum = c(2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 3L, 2L),
final_sum = c(7L, 8L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L)),
class = "data.frame", row.names = c(NA, -11L))
我在 SO 上查找了类似的问题并找到了这个 但它似乎无法帮助我解决我的问题。
另一个相关的 post 是 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
即第二个参数,return inconsistent
否则 consistent
.
- 现在由于提供了
.init
,结果将比提供的值大一个值,因此删除了它的第一个值 [-1]
df <- structure(list(
TUserId = c(115L, 115L, 115L, 209L, 209L, 209L, 209L, 371L, 371L, 371L, 371L),
SUID = c(201L, 309L, 404L, 245L, 398L, 510L, 602L, 111L, 115L, 123L, 124L),
mid_sum = c(2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 3L, 2L),
final_sum = c(7L, 8L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 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-06-15 创建
我正在处理一个数据框 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
所示,在期中考试中给学生相似分数的老师在期末考试中给出的分数不一致,如final_sum
。如果在数据中发现这种不一致,我想添加一列Status
来记录这个inconsistency
。
要求:
a- 为此,我的规则是如果 mid_sum
和 final_sum
按升序排序,就像我在这个示例数据框 df
中所做的那样。我想确定在 mid_sum
和 final_sum
.
b- 如果数据没有排序,能做到吗?
示例 1:
例如,对于SUID = 309
,mid_sum
是从前面的mid_sum
减去的。所以它应该被标记为inconsistent
。它应该只发生在被同一个老师 TUserId
打分的学生身上,在这种情况下是 115
.
示例 2:
同样,对于SUID = 602
,mid_sum
是从前面的mid_sum
减去的。所以它应该被标记为inconsistent
。同样,这是给同一个老师的TUserId = 209
为了进一步详细说明,我想要这样的输出:
输出:
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()
数据框的dput()
如下:
dput(df)
structure(list(
TUserId = c(115L, 115L, 115L, 209L, 209L, 209L, 209L, 371L, 371L, 371L, 371L),
SUID = c(201L, 309L, 404L, 245L, 398L, 510L, 602L, 111L, 115L, 123L, 124L),
mid_sum = c(2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 3L, 2L),
final_sum = c(7L, 8L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L)),
class = "data.frame", row.names = c(NA, -11L))
我在 SO 上查找了类似的问题并找到了这个
任何有关如何解决此问题的建议将不胜感激。
谢谢!
这是我们测试滞后差异符号的一种相当简单的方法。如果 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
即第二个参数,returninconsistent
否则consistent
. - 现在由于提供了
.init
,结果将比提供的值大一个值,因此删除了它的第一个值[-1]
df <- structure(list(
TUserId = c(115L, 115L, 115L, 209L, 209L, 209L, 209L, 371L, 371L, 371L, 371L),
SUID = c(201L, 309L, 404L, 245L, 398L, 510L, 602L, 111L, 115L, 123L, 124L),
mid_sum = c(2L, 1L, 1L, 2L, 2L, 2L, 1L, 2L, 1L, 3L, 2L),
final_sum = c(7L, 8L, 9L, 10L, 10L, 10L, 10L, 11L, 11L, 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-06-15 创建