【问题标题】:Updating based on Condition of Previous Occurrence根据先前发生的条件进行更新
【发布时间】:2021-10-26 15:24:46
【问题描述】:

我有一个数据框

  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

我的目标是在每次试验中添加一列,指定刺激是最近(在之前的试验中)被选择还是被拒绝。

想要的结果

  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

这就是我将如何更新我的表格

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 函数以将其也返回

 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)
                      )
                      ]

虽然这并没有给我正确的答案。有人知道我哪里出错了吗?

【问题讨论】:

  • 为什么是Previous_stim1 row2 NaN?
  • 因为以前没有选择或拒绝它的实例
  • 对不起,只是为了了解逻辑。 stim1 第 1 行 =2。这不是stim1row2=3 的前一个实例吗?
  • 当我查看以前的实例时,我只检查选择和拒绝的列。所以第 2 行 ==3 和 3 中的 stim1 从未出现过,所以它的 NaN。但是 stim2==2 是在之前的试验中选择的,所以 Previous_stim2=chosen
  • 那么,Previous_stim1[5] 将是 Rejected

标签: r dataframe dplyr data-wrangling


【解决方案1】:

对于更新 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

【讨论】:

  • 我在更新 2 中将后续问题添加到您的解决方案中,因为我的最终目标是对结果进行编码。我还不熟悉 data.frame - 我需要为此创建四个不同的函数吗?再次感谢!
  • 再次感谢您的帮助!我用最后一个问题更新了问题-想知道是否有一种简单的方法可以返回该附加信息(这对重复的地方和不重复的地方)
  • @user15791858 我想这是迄今为止我能做的最简单的方法......
  • 我尝试使用你的函数来返回最后的刺激(参见最新更新),但我似乎有点不对劲——知道我做错了什么
【解决方案2】:

这是在 ThomasIsCoding Check if value of column A is present in the same row or previous rows of column B 的帮助下生成的解决方案:这里还有其他答案,足以满足您的解决方案!你可以改变和调整哪一个适合你。我选择了 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

【讨论】:

  • 不错,伙计。这个还没试过,但我想到了“使用row_number()的东西”。
  • 是的,这个答案使用 row_number stackoverflow.com/a/68944025/4663008 而另一个答案也使用 rowwise 来解决。
  • 谢谢 tarjae,这非常有帮助。我共享的数据框部分工作得很好,但由于某种原因,它不再正确分类。我用您建议的脚本的输出编辑了原始问题。你知道为什么会这样吗?再次感谢您的帮助
【解决方案3】:

我认为您需要更正上表中的预期结果。但看起来您正在寻找 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")) 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 2023-03-22
    相关资源
    最近更新 更多