使用 ifelse() 识别数据中不一致的响应
Use ifelse() to Identify inconsistent responses in data
我有一个关于青春期状态的重复问题的回答的长格式数据框 vb_
大约每年在 9、10、11、13、14、15、16 和 17 岁时被问到。
每年参与者都被要求从 1 到 5 对他们的发展进行评分,其中 1 表示最不发达,5 表示最发达。
我想使用 R 的 ifelse()
来识别不一致的响应,即那些报告某一年的阶段低于前几年的响应。
这是一些 20 人的假示例数据:
vb <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L,
6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L,
8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L,
10L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L,
11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L,
13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L,
15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L,
16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L,
18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 19L, 19L,
19L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L), age = c(9L, 10L,
11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L,
17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L,
14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L,
10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L,
16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L,
13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L,
9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L,
15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L,
11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L,
17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L,
14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L,
10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L,
16L, 17L), vb_ = c(1L, 1L, 1L, 3L, 4L, 4L, 4L, 5L, 2L, 2L, 3L,
4L, 5L, 5L, 5L, 5L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 2L, 1L, 3L,
4L, 4L, 5L, 5L, 5L, 2L, 2L, 1L, 3L, 4L, 3L, 4L, 4L, 1L, 1L, 1L,
3L, 4L, 4L, 5L, 5L, 1L, 1L, 2L, 4L, 4L, 4L, 5L, 5L, 2L, 2L, 2L,
4L, 5L, 4L, 4L, 5L, 2L, 2L, 1L, 4L, 5L, 5L, 5L, 5L, 1L, 2L, 3L,
4L, 5L, 5L, 4L, 5L, 1L, 1L, 1L, 4L, 4L, 5L, 5L, 5L, 1L, 1L, 1L,
1L, 4L, 4L, 4L, 4L, 1L, 1L, 3L, 4L, 4L, 4L, 5L, 5L, 1L, 1L, 1L,
4L, 4L, 5L, 5L, 5L, 2L, 2L, 2L, 2L, 4L, 4L, 5L, 5L, 2L, 3L, 3L,
4L, 4L, 5L, 5L, 5L, 1L, 1L, 2L, 2L, 4L, 5L, 5L, 5L, 1L, 1L, 1L,
3L, 3L, 4L, 5L, 5L, 1L, 1L, 1L, 2L, 4L, 4L, 4L, 4L, 1L, 1L, 1L,
2L, 4L, 4L, 4L, 4L)), class = "data.frame", row.names = c(NA,
-160L), .Names = c("id", "age", "vb_"))
如果您坚持 ifelse
方法,您可以这样做:
vb <- vb[order(vb$id, vb$age), ]
vb$inconsistent <- ifelse(vb$id == lag(vb$id),
ifelse(vb$vb_ < lag(vb$vb_), "inconsistent", ""),
"")
vb$inconsistent[1] <- ""
id age vb_ inconsistent
1 1 9 1
2 1 10 1
3 1 11 1
4 1 13 3
5 1 14 4
6 1 15 4
7 1 16 4
8 1 17 5
9 2 9 2
10 2 10 2
11 2 11 3
12 2 13 4
13 2 14 5
14 2 15 5
15 2 16 5
16 2 17 5
17 3 9 2
18 3 10 3
19 3 11 3
20 3 13 3
21 3 14 4
22 3 15 4
23 3 16 4
24 3 17 5
25 4 9 2
26 4 10 1 inconsistent
27 4 11 3
...
或者 dplyr
的一种方法是:
library(dplyr)
vb %>%
group_by(id) %>%
arrange(id, age) %>%
mutate(vb_diff = vb_ - lag(vb_)) %>%
filter(vb_diff < 0)
# A tibble: 6 x 4
# Groups: id [5]
id age vb_ vb_diff
<int> <int> <int> <int>
1 4 10 1 -1
2 5 11 1 -1
3 5 15 3 -1
4 8 15 4 -1
5 9 11 1 -1
6 10 16 4 -1
给你。
vb <- vb[order(vb$id, vb$age),]
vb$decreasingdevelopment <- c(0, diff(vb$vb_))<0 #difference between this score and previous <0
vb$sameperson <- c(0, diff(vb$id))==0 #is this the same participant than previous
vb$inconsistency <- vb$decreasingdevelopment&vb$sameperson #ifelse(vb$devdiff&vb$sameperson, T, F)
which(vb$inconsistency)
#[1] 26 35 38 62 67 79
请注意,可以使用 ifelse()
,但不是必需的。
PS:为了答案的完整性,您应该始终使用以下内容:
vb$inconsistency_robust <- apply(vb, 1, function(x) length(which(vb$vb_>x["vb_"]&vb$age<x["age"]&vb$id==x["id"]))>0)
#x["decreasingdevelopment"]&x["sameperson"])
all.equal(which(vb$inconsistency_robust), which(vb$inconsistency))
#> which(vb$inconsistency_robust)
#[1] 26 35 38 62 63 67 79
#> which(vb$inconsistency)
#[1] 26 35 38 62 67 79
请注意稳健的方法如何发现所有不一致的发生,而我这里更天真的 ifelse()
方法只比较行与行。
我有一个关于青春期状态的重复问题的回答的长格式数据框 vb_
大约每年在 9、10、11、13、14、15、16 和 17 岁时被问到。
每年参与者都被要求从 1 到 5 对他们的发展进行评分,其中 1 表示最不发达,5 表示最发达。
我想使用 R 的 ifelse()
来识别不一致的响应,即那些报告某一年的阶段低于前几年的响应。
这是一些 20 人的假示例数据:
vb <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L,
2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L,
4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L,
6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L,
8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L,
10L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L,
11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L,
13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L,
15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L,
16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L,
18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 19L, 19L,
19L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L), age = c(9L, 10L,
11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L,
17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L,
14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L,
10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L,
16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L,
13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L,
9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L,
15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L,
11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L,
17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L,
14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L,
10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L,
16L, 17L), vb_ = c(1L, 1L, 1L, 3L, 4L, 4L, 4L, 5L, 2L, 2L, 3L,
4L, 5L, 5L, 5L, 5L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 2L, 1L, 3L,
4L, 4L, 5L, 5L, 5L, 2L, 2L, 1L, 3L, 4L, 3L, 4L, 4L, 1L, 1L, 1L,
3L, 4L, 4L, 5L, 5L, 1L, 1L, 2L, 4L, 4L, 4L, 5L, 5L, 2L, 2L, 2L,
4L, 5L, 4L, 4L, 5L, 2L, 2L, 1L, 4L, 5L, 5L, 5L, 5L, 1L, 2L, 3L,
4L, 5L, 5L, 4L, 5L, 1L, 1L, 1L, 4L, 4L, 5L, 5L, 5L, 1L, 1L, 1L,
1L, 4L, 4L, 4L, 4L, 1L, 1L, 3L, 4L, 4L, 4L, 5L, 5L, 1L, 1L, 1L,
4L, 4L, 5L, 5L, 5L, 2L, 2L, 2L, 2L, 4L, 4L, 5L, 5L, 2L, 3L, 3L,
4L, 4L, 5L, 5L, 5L, 1L, 1L, 2L, 2L, 4L, 5L, 5L, 5L, 1L, 1L, 1L,
3L, 3L, 4L, 5L, 5L, 1L, 1L, 1L, 2L, 4L, 4L, 4L, 4L, 1L, 1L, 1L,
2L, 4L, 4L, 4L, 4L)), class = "data.frame", row.names = c(NA,
-160L), .Names = c("id", "age", "vb_"))
如果您坚持 ifelse
方法,您可以这样做:
vb <- vb[order(vb$id, vb$age), ]
vb$inconsistent <- ifelse(vb$id == lag(vb$id),
ifelse(vb$vb_ < lag(vb$vb_), "inconsistent", ""),
"")
vb$inconsistent[1] <- ""
id age vb_ inconsistent
1 1 9 1
2 1 10 1
3 1 11 1
4 1 13 3
5 1 14 4
6 1 15 4
7 1 16 4
8 1 17 5
9 2 9 2
10 2 10 2
11 2 11 3
12 2 13 4
13 2 14 5
14 2 15 5
15 2 16 5
16 2 17 5
17 3 9 2
18 3 10 3
19 3 11 3
20 3 13 3
21 3 14 4
22 3 15 4
23 3 16 4
24 3 17 5
25 4 9 2
26 4 10 1 inconsistent
27 4 11 3
...
或者 dplyr
的一种方法是:
library(dplyr)
vb %>%
group_by(id) %>%
arrange(id, age) %>%
mutate(vb_diff = vb_ - lag(vb_)) %>%
filter(vb_diff < 0)
# A tibble: 6 x 4
# Groups: id [5]
id age vb_ vb_diff
<int> <int> <int> <int>
1 4 10 1 -1
2 5 11 1 -1
3 5 15 3 -1
4 8 15 4 -1
5 9 11 1 -1
6 10 16 4 -1
给你。
vb <- vb[order(vb$id, vb$age),]
vb$decreasingdevelopment <- c(0, diff(vb$vb_))<0 #difference between this score and previous <0
vb$sameperson <- c(0, diff(vb$id))==0 #is this the same participant than previous
vb$inconsistency <- vb$decreasingdevelopment&vb$sameperson #ifelse(vb$devdiff&vb$sameperson, T, F)
which(vb$inconsistency)
#[1] 26 35 38 62 67 79
请注意,可以使用 ifelse()
,但不是必需的。
PS:为了答案的完整性,您应该始终使用以下内容:
vb$inconsistency_robust <- apply(vb, 1, function(x) length(which(vb$vb_>x["vb_"]&vb$age<x["age"]&vb$id==x["id"]))>0)
#x["decreasingdevelopment"]&x["sameperson"])
all.equal(which(vb$inconsistency_robust), which(vb$inconsistency))
#> which(vb$inconsistency_robust)
#[1] 26 35 38 62 63 67 79
#> which(vb$inconsistency)
#[1] 26 35 38 62 67 79
请注意稳健的方法如何发现所有不一致的发生,而我这里更天真的 ifelse()
方法只比较行与行。