根据先前发生的条件更新
Updating based on Condition of Previous Occurrence
我有一个数据框
stim1 stim2 Chosen Rejected
1: 2 1 2 1
2: 3 2 2 3
3: 3 1 1 3
4: 2 3 3 2
5: 1 3 1 3
我的 objective 在每次试验中添加一列,指定刺激是最近(在以前的试验中)选择还是拒绝。
期望的结果
stim1 stim2 Chosen Rejected Previous_stim1 Previous_stim2
1: 2 1 2 1 NaN NaN
2: 3 2 2 3 NaN Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
任何帮助将不胜感激!
更新
TarJae 提出了一个非常有用的建议,帮助我正确地对我共享的数据框进行了分类。我没有提到它实际上是更大数据框的一部分,并且出于某种原因,这种方法很快就停止正确分类
stim1 stim2 Chosen Rejected Previous_stim1 Previous_stim2
1: 2 1 2 1 <NA> <NA>
2: 3 2 2 3 <NA> Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
6: 2 1 1 2 Chosen Chosen
7: 2 3 2 3 Chosen Chosen
8: 3 1 1 3 Chosen Chosen
9: 2 1 2 1 Chosen Chosen
例如,第 6 行中的 stim1==2。最近,2 被拒绝(第 4 行),但该方法将其归类为已选择。
知道这是怎么回事吗?
再次感谢大家的帮助。
更新 2
非常感谢您的帮助。但是说我也有一个关于“结果”的专栏。
stim1 stim2 Chosen Rejected outcome Previous_stim 1 Previous_stim 2
1: 15 13 15 13 1 <NA> <NA>
2: 13 14 14 13 1 Rejected <NA>
3: 14 15 14 15 1 Chosen Chosen
4: 14 13 14 13 0 Chosen Rejected
5: 13 15 13 15 0 Rejected Rejected
6: 14 15 14 15 1 Chosen Rejected
7: 15 13 15 13 1 Rejected Chosen
8: 14 15 14 15 0 Chosen Chosen
I want to encode whether it was
1) most recently chosen and outcome=1 (can be coded as 1)
2) most recently chosen and outcome=0 (can be coded as 2)
3) most recently rejected and outcome=1 (can be coded as 3)
4) most recently rejected and outcome=0 (can be coded as 4)
是否有一种简单的方法来修改代码以实现这一点?
期望的输出
stim1 stim2 Chosen Rejected outcome Previous_stim 1 Previous_stim 2 Left_type right_type
1 2 3 2 3 1 <NA> <NA> NaN NaN
2 1 3 3 1 1 <NA> Rejected NaN 3
3 2 1 1 2 1 Chosen Rejected 1 3
4 1 2 1 2 0 Chosen Rejected 1 3
5 3 1 3 1 1 Chosen Chosen 1 2
最后跟进
最后,我想添加一个列来检查在之前的试验中选择的刺激(我将其称为最近被拒绝的相关刺激试验)是否与我当前的替代刺激相同
例如如果有
stim1 stim2 Chosen Rejected Previous_stim1 Previous_stim2
1: 2 1 2 1 NaN NaN
2: 3 2 2 3 NaN Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
这是我更新 table
的方式
in trial 3, previous_stim1 (i.e 3) was previously rejectedin favor of 2 (from trial 2) and not in favor of 1 (which is the current alternative) and so Current_alternative_left=0.
Similarly, previous_stim2 (i.e 1)was previously
rejected but that was rejected in favor of 2 (from trial 1)
and so current_alternative_right=0
On the other hand, in trial 4 stim1=2
was previously chosen relative to the same
刺激,因为它目前正在对抗 (3)
所以 current_alternative_right=1
期望的输出
stim1 stim2 Chosen Rejected outcome Previous_stim 1 Previous_stim 2 Left_type right_type
1 2 3 2 3 1 <NA> <NA> NaN NaN
2 1 3 3 1 1 <NA> Rejected NaN 3
3 2 1 1 2 1 Chosen Rejected 1 3
4 1 2 1 2 0 Chosen Rejected 1 3
5 3 1 3 1 1 Chosen Chosen 1 2
Current_alternative_left Current_alternative_right
NaN NaN
NaN 0
0 0
1 0
1 0
我是 data.table 的新手,但我也尝试将 ThomasisCoding 函数复制到 return 这以及
h <- function(stim, cr) {
stim_chosen <- rep(NA,length(stim))
for (k in seq_along(stim)[-1]) {
ind <- which(cr[1:(k - 1), , drop = FALSE] == stim[k], arr.ind = TRUE)
if (length(ind)) {
stim_chosen[k] <- stim[tail(ind,1)[,"row"]]
}
}
stim_chosen
}
setDT(df)[ ,
paste0("Chosen_Last", 1:2) := lapply(
.(stim1, stim2),
h,
cr = cbind(Chosen,Rejected)
)
]
虽然这并没有给我正确的答案。有人知道我哪里错了吗?
我认为您需要更正上述 table 中的预期结果。但是看起来您正在寻找 lag
动词,当它与 if_else
:
一起使用时可以帮助解决这个问题
library(dplyr)
tbl <- tibble(stim1 = c(2,3,3,2,1), stim2 = c(1,2,1,3,3),
chosen = c(2,2,1,3,1), rejected = c(1,3,3,2,3))
tbl %>%
mutate(Previous_stim1 = if_else(lag(tbl$chosen) == lag(stim1), "Chosen", "Rejected")) %>%
mutate(Previous_stim2 = if_else(lag(tbl$chosen) == lag(stim2), "Chosen", "Rejected"))
这是在 ThomasIsCoding 的帮助下生成的解决方案:这里还有其他答案,足以满足您的解决方案!你可以改变和适应哪一个适合你。我选择了ThomasIsCoding提供的第一个
主要任务是检查其他列的所有先前行中的值
library(dplyr)
df %>%
mutate(x = replace(rep(NA, length(Chosen)), match(stim1, lag(Chosen)) <= seq_along(stim1), "Chosen"),
y = replace(rep(NA, length(Rejected)), match(stim1, lag(Rejected)) <= seq_along(stim1), "Rejected"),
a = replace(rep(NA, length(Chosen)), match(stim2, lag(Chosen)) <= seq_along(stim2), "Chosen"),
b = replace(rep(NA, length(Rejected)), match(stim2, lag(Rejected)) <= seq_along(stim2), "Rejected"),
Previous_stim1 = coalesce(x, y),
Previous_stim2 = coalesce(a, b)) %>%
select(stim1, stim2, Chosen, Rejected, Previous_stim1, Previous_stim2)
stim1 stim2 Chosen Rejected Previous_stim1 Previous_stim2
1: 2 1 2 1 <NA> <NA>
2: 3 2 2 3 <NA> Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
对于更新 2
setDT(df)[
,
paste0("Previous_stim", 1:2) := lapply(
.(stim1, stim2),
f,
cr = cbind(Chosen, Rejected)
)
][
,
paste0(c("left", "right"), "type") := lapply(.SD, function(x) 2 * (x == "Rejected") + 2 - outcome),
.SDcols = patterns("Previous")
][]
给予
stim1 stim2 Chosen Rejected outcome Previous_stim1 Previous_stim2 lefttype
1: 2 1 2 1 1 <NA> <NA> NA
2: 3 2 2 3 1 <NA> Chosen NA
3: 3 1 1 3 1 Rejected Rejected 3
4: 2 3 3 2 0 Chosen Rejected 2
5: 1 3 1 3 0 Chosen Chosen 2
6: 2 1 1 2 1 Rejected Chosen 3
7: 2 3 2 3 1 Rejected Rejected 3
8: 3 1 1 3 0 Rejected Chosen 4
9: 2 1 2 1 0 Chosen Chosen 2
righttype
1: NA
2: 1
3: 3
4: 4
5: 2
6: 1
7: 3
8: 2
9: 2
数据
> dput(df)
structure(list(stim1 = c(2L, 3L, 3L, 2L, 1L, 2L, 2L, 3L, 2L),
stim2 = c(1L, 2L, 1L, 3L, 3L, 1L, 3L, 1L, 1L), Chosen = c(2L,
2L, 1L, 3L, 1L, 1L, 2L, 1L, 2L), Rejected = c(1L, 3L, 3L,
2L, 3L, 2L, 3L, 3L, 1L), outcome = c(1, 1, 1, 0, 0, 1, 1,
0, 0)), class = "data.frame", row.names = c(NA, -9L))
根据您的更新,您可以通过定义自定义函数来尝试以下代码 f
f <- function(stim, cr) {
res <- rep(NA, length(stim))
for (k in seq_along(stim)[-1]) {
ind <- which(cr[1:(k - 1), , drop = FALSE] == stim[k], arr.ind = TRUE)
if (length(ind)) {
res[k] <- colnames(cr)[tail(ind[, "col"][order(ind[, "row"])], 1)]
}
}
res
}
setDT(df)[
,
paste("Previous_stim", 1:2) := lapply(
.(stim1, stim2),
f,
cr = cbind(Chosen, Rejected)
)
][]
你会看到
> setDT(df)[, paste("Previous_stim",1:2) := lapply(.(stim1,stim2),f, cr = cbind(Chosen, Rejected))][]
stim1 stim2 Chosen Rejected Previous_stim 1 Previous_stim 2
1: 2 1 2 1 <NA> <NA>
2: 3 2 2 3 <NA> Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
6: 2 1 1 2 Rejected Chosen
7: 2 3 2 3 Rejected Rejected
8: 3 1 1 3 Rejected Chosen
9: 2 1 2 1 Chosen Chosen
我有一个数据框
stim1 stim2 Chosen Rejected
1: 2 1 2 1
2: 3 2 2 3
3: 3 1 1 3
4: 2 3 3 2
5: 1 3 1 3
我的 objective 在每次试验中添加一列,指定刺激是最近(在以前的试验中)选择还是拒绝。
期望的结果
stim1 stim2 Chosen Rejected Previous_stim1 Previous_stim2
1: 2 1 2 1 NaN NaN
2: 3 2 2 3 NaN Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
任何帮助将不胜感激!
更新
TarJae 提出了一个非常有用的建议,帮助我正确地对我共享的数据框进行了分类。我没有提到它实际上是更大数据框的一部分,并且出于某种原因,这种方法很快就停止正确分类
stim1 stim2 Chosen Rejected Previous_stim1 Previous_stim2
1: 2 1 2 1 <NA> <NA>
2: 3 2 2 3 <NA> Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
6: 2 1 1 2 Chosen Chosen
7: 2 3 2 3 Chosen Chosen
8: 3 1 1 3 Chosen Chosen
9: 2 1 2 1 Chosen Chosen
例如,第 6 行中的 stim1==2。最近,2 被拒绝(第 4 行),但该方法将其归类为已选择。
知道这是怎么回事吗?
再次感谢大家的帮助。
更新 2
非常感谢您的帮助。但是说我也有一个关于“结果”的专栏。
stim1 stim2 Chosen Rejected outcome Previous_stim 1 Previous_stim 2
1: 15 13 15 13 1 <NA> <NA>
2: 13 14 14 13 1 Rejected <NA>
3: 14 15 14 15 1 Chosen Chosen
4: 14 13 14 13 0 Chosen Rejected
5: 13 15 13 15 0 Rejected Rejected
6: 14 15 14 15 1 Chosen Rejected
7: 15 13 15 13 1 Rejected Chosen
8: 14 15 14 15 0 Chosen Chosen
I want to encode whether it was
1) most recently chosen and outcome=1 (can be coded as 1)
2) most recently chosen and outcome=0 (can be coded as 2)
3) most recently rejected and outcome=1 (can be coded as 3)
4) most recently rejected and outcome=0 (can be coded as 4)
是否有一种简单的方法来修改代码以实现这一点?
期望的输出
stim1 stim2 Chosen Rejected outcome Previous_stim 1 Previous_stim 2 Left_type right_type
1 2 3 2 3 1 <NA> <NA> NaN NaN
2 1 3 3 1 1 <NA> Rejected NaN 3
3 2 1 1 2 1 Chosen Rejected 1 3
4 1 2 1 2 0 Chosen Rejected 1 3
5 3 1 3 1 1 Chosen Chosen 1 2
最后跟进
最后,我想添加一个列来检查在之前的试验中选择的刺激(我将其称为最近被拒绝的相关刺激试验)是否与我当前的替代刺激相同
例如如果有
stim1 stim2 Chosen Rejected Previous_stim1 Previous_stim2
1: 2 1 2 1 NaN NaN
2: 3 2 2 3 NaN Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
这是我更新 table
的方式in trial 3, previous_stim1 (i.e 3) was previously rejectedin favor of 2 (from trial 2) and not in favor of 1 (which is the current alternative) and so Current_alternative_left=0.
Similarly, previous_stim2 (i.e 1)was previously
rejected but that was rejected in favor of 2 (from trial 1)
and so current_alternative_right=0
On the other hand, in trial 4 stim1=2
was previously chosen relative to the same
刺激,因为它目前正在对抗 (3) 所以 current_alternative_right=1
期望的输出
stim1 stim2 Chosen Rejected outcome Previous_stim 1 Previous_stim 2 Left_type right_type
1 2 3 2 3 1 <NA> <NA> NaN NaN
2 1 3 3 1 1 <NA> Rejected NaN 3
3 2 1 1 2 1 Chosen Rejected 1 3
4 1 2 1 2 0 Chosen Rejected 1 3
5 3 1 3 1 1 Chosen Chosen 1 2
Current_alternative_left Current_alternative_right
NaN NaN
NaN 0
0 0
1 0
1 0
我是 data.table 的新手,但我也尝试将 ThomasisCoding 函数复制到 return 这以及
h <- function(stim, cr) {
stim_chosen <- rep(NA,length(stim))
for (k in seq_along(stim)[-1]) {
ind <- which(cr[1:(k - 1), , drop = FALSE] == stim[k], arr.ind = TRUE)
if (length(ind)) {
stim_chosen[k] <- stim[tail(ind,1)[,"row"]]
}
}
stim_chosen
}
setDT(df)[ ,
paste0("Chosen_Last", 1:2) := lapply(
.(stim1, stim2),
h,
cr = cbind(Chosen,Rejected)
)
]
虽然这并没有给我正确的答案。有人知道我哪里错了吗?
我认为您需要更正上述 table 中的预期结果。但是看起来您正在寻找 lag
动词,当它与 if_else
:
library(dplyr)
tbl <- tibble(stim1 = c(2,3,3,2,1), stim2 = c(1,2,1,3,3),
chosen = c(2,2,1,3,1), rejected = c(1,3,3,2,3))
tbl %>%
mutate(Previous_stim1 = if_else(lag(tbl$chosen) == lag(stim1), "Chosen", "Rejected")) %>%
mutate(Previous_stim2 = if_else(lag(tbl$chosen) == lag(stim2), "Chosen", "Rejected"))
这是在 ThomasIsCoding
主要任务是检查其他列的所有先前行中的值
library(dplyr)
df %>%
mutate(x = replace(rep(NA, length(Chosen)), match(stim1, lag(Chosen)) <= seq_along(stim1), "Chosen"),
y = replace(rep(NA, length(Rejected)), match(stim1, lag(Rejected)) <= seq_along(stim1), "Rejected"),
a = replace(rep(NA, length(Chosen)), match(stim2, lag(Chosen)) <= seq_along(stim2), "Chosen"),
b = replace(rep(NA, length(Rejected)), match(stim2, lag(Rejected)) <= seq_along(stim2), "Rejected"),
Previous_stim1 = coalesce(x, y),
Previous_stim2 = coalesce(a, b)) %>%
select(stim1, stim2, Chosen, Rejected, Previous_stim1, Previous_stim2)
stim1 stim2 Chosen Rejected Previous_stim1 Previous_stim2
1: 2 1 2 1 <NA> <NA>
2: 3 2 2 3 <NA> Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
对于更新 2
setDT(df)[
,
paste0("Previous_stim", 1:2) := lapply(
.(stim1, stim2),
f,
cr = cbind(Chosen, Rejected)
)
][
,
paste0(c("left", "right"), "type") := lapply(.SD, function(x) 2 * (x == "Rejected") + 2 - outcome),
.SDcols = patterns("Previous")
][]
给予
stim1 stim2 Chosen Rejected outcome Previous_stim1 Previous_stim2 lefttype
1: 2 1 2 1 1 <NA> <NA> NA
2: 3 2 2 3 1 <NA> Chosen NA
3: 3 1 1 3 1 Rejected Rejected 3
4: 2 3 3 2 0 Chosen Rejected 2
5: 1 3 1 3 0 Chosen Chosen 2
6: 2 1 1 2 1 Rejected Chosen 3
7: 2 3 2 3 1 Rejected Rejected 3
8: 3 1 1 3 0 Rejected Chosen 4
9: 2 1 2 1 0 Chosen Chosen 2
righttype
1: NA
2: 1
3: 3
4: 4
5: 2
6: 1
7: 3
8: 2
9: 2
数据
> dput(df)
structure(list(stim1 = c(2L, 3L, 3L, 2L, 1L, 2L, 2L, 3L, 2L),
stim2 = c(1L, 2L, 1L, 3L, 3L, 1L, 3L, 1L, 1L), Chosen = c(2L,
2L, 1L, 3L, 1L, 1L, 2L, 1L, 2L), Rejected = c(1L, 3L, 3L,
2L, 3L, 2L, 3L, 3L, 1L), outcome = c(1, 1, 1, 0, 0, 1, 1,
0, 0)), class = "data.frame", row.names = c(NA, -9L))
根据您的更新,您可以通过定义自定义函数来尝试以下代码 f
f <- function(stim, cr) {
res <- rep(NA, length(stim))
for (k in seq_along(stim)[-1]) {
ind <- which(cr[1:(k - 1), , drop = FALSE] == stim[k], arr.ind = TRUE)
if (length(ind)) {
res[k] <- colnames(cr)[tail(ind[, "col"][order(ind[, "row"])], 1)]
}
}
res
}
setDT(df)[
,
paste("Previous_stim", 1:2) := lapply(
.(stim1, stim2),
f,
cr = cbind(Chosen, Rejected)
)
][]
你会看到
> setDT(df)[, paste("Previous_stim",1:2) := lapply(.(stim1,stim2),f, cr = cbind(Chosen, Rejected))][]
stim1 stim2 Chosen Rejected Previous_stim 1 Previous_stim 2
1: 2 1 2 1 <NA> <NA>
2: 3 2 2 3 <NA> Chosen
3: 3 1 1 3 Rejected Rejected
4: 2 3 3 2 Chosen Rejected
5: 1 3 1 3 Chosen Chosen
6: 2 1 1 2 Rejected Chosen
7: 2 3 2 3 Rejected Rejected
8: 3 1 1 3 Rejected Chosen
9: 2 1 2 1 Chosen Chosen