【问题标题】:Using case_when and lag() together?一起使用 case_when 和 lag() ?
【发布时间】:2021-11-09 18:35:28
【问题描述】:

提前道歉,这个问题很大 - 我正在尝试包含尽可能多的细节。下面的示例表是行为任务的输出。在 448 次试验中,每一次试验的开始和结束都有视觉掩码、一个视觉素数(六个可能的素数,用代码 1:6 表示)和一个做出响应的目标(六个可能,表示通过代码 7:12)。对目标的准确度用 1(正确)或 0(错误)表示。

我现在需要向响应行添加新代码。这些新闻代码必须是代表目标类型和准确性的每种组合的新数字。例如,如果有一个正方形目标(代码 12),并且参与者是正确的(准确度 = 1),则新代码将为 25;如果有一个方形目标 (12) 并且它们不正确 (Accuracy=0),则新代码将为 26,以此类推,目标 (7:12) 和准确度 (0:1) 的每个组合(总共 12 个组合)。

Trial Label Code Accuracy
1 Pre-Mask 13 1
1 BluePrime 6 1
1 SqureTarget 12 1
1 Post-Mask 14 1
1 Response NA 1
2 Pre-Mask 13 0
2 RedPrime 4 0
2 CircleTarget 9 0
2 Post-Mask 14 0
2 Response NA 0

基本上,我需要一个条件语句,根据缺失值之前两行中两个不同列的信息替换 NA。输出应如下所示:

Trial Label Code Accuracy
1 Pre-Mask 13 1
1 BluePrime 6 1
1 SqureTarget 12 1
1 Post-Mask 14 1
1 Response 25 1
2 Pre-Mask 13 0
2 RedPrime 4 0
2 CircleTarget 9 0
2 Post-Mask 14 0
2 Response 20 0

这是包含所有新可能组合的表格:

When target is.. And Accuracy is... New Code #
7 1 15
7 0 16
8 1 17
8 0 18
9 1 19
9 0 20
10 1 21
10 0 22
11 1 23
11 0 24
12 1 25
12 0 26

我尝试了 lag() 和 case_when() 的不同组合,但是当我开始输入时,我意识到我真的不知道如何构造参数(我对 R 和编程还是很陌生) .我知道我可以在 Excel 中手动输入数字,但我希望在 R 中在某种程度上实现自动化。我意识到这些信息也可以很容易地放入新行中,但是为了下一个程序,我是用于理解代码值,它们都需要按照它们实时出现的顺序在同一列中(响应输入将始终遵循后视觉掩码,代码 14)。

如果需要任何澄清,请告诉我。任何帮助表示赞赏!

【问题讨论】:

    标签: r dplyr conditional-statements data-manipulation


    【解决方案1】:

    我认为这符合你的逻辑:

    library(dplyr)
    library(tidyr)
    
    input %>%
      ## join the new values to the original data on their current rows
      left_join(lookup, by = c("Code", "Accuracy")) %>%
      ## do all subsequent operations within each Trial group
      group_by(Trial) %>%
      ## Fill in missing `New_Code` values based on the previous non-missing value
      fill(New_Code, .direction = "down") %>%
      ## replace any `Code` missing values with the `New_Code` value
      mutate(Code = coalesce(Code, New_Code))
    
    # # A tibble: 10 x 5
    # # Groups:   Trial [2]
    # Trial Label         Code Accuracy New_Code
    # <int> <chr>        <int>    <int>    <int>
    #  1     1 Pre-Mask        13        1       NA
    #  2     1 BluePrime        6        1       NA
    #  3     1 SqureTarget     12        1       25
    #  4     1 Post-Mask       14        1       25
    #  5     1 Response        25        1       25
    #  6     2 Pre-Mask        13        0       NA
    #  7     2 RedPrime         4        0       NA
    #  8     2 CircleTarget     9        0       20
    #  9     2 Post-Mask       14        0       20
    # 10     2 Response        20        0       20
    

    当然,您可以通过添加 ... %&gt;% select(-New_Code) 来删除 New_Code 列——为了清楚起见,我将其保留在上面。


    使用这些数据:

    input = read.table(text = 'Trial    Label   Code    Accuracy
    1   Pre-Mask    13  1
    1   BluePrime   6   1
    1   SqureTarget 12  1
    1   Post-Mask   14  1
    1   Response    NA  1
    2   Pre-Mask    13  0
    2   RedPrime    4   0
    2   CircleTarget    9   0
    2   Post-Mask   14  0
    2   Response    NA  0', header = T)
    
    lookup = read.table(text = 'Code    Accuracy    New_Code
    7   1   15
    7   0   16
    8   1   17
    8   0   18
    9   1   19
    9   0   20
    10  1   21
    10  0   22
    11  1   23
    11  0   24
    12  1   25
    12  0   26', header = TRUE)
    

    【讨论】:

      【解决方案2】:

      你可以这样做:

      1. 我将第一个表读为“acc”
      2. 我已将最后一个表读为“目标”
      merge <- merge(x = acc, y = target, by = c("Code", "Accuracy"), all.x= TRUE)
         Code Accuracy Trial        Label newCode
      1     4        0     2     RedPrime      NA
      2     6        1     1    BluePrime      NA
      3     9        0     2 CircleTarget      20
      4    12        1     1  SqureTarget      25
      5    13        0     2     Pre-Mask      NA
      6    13        1     1     Pre-Mask      NA
      7    14        0     2    Post-Mask      NA
      8    14        1     1    Post-Mask      NA
      9    NA        0     2     Response      NA
      10   NA        1     1     Response      NA
      
      newCodes <- merge[!is.na(merge$newCode),c("Trial", "newCode")]
      merge <- merge(merge, newCodes, "Trial")  
      
        Trial Code Accuracy        Label newCode.x newCode.y
      1      1    6        1    BluePrime        NA        25
      2      1   12        1  SqureTarget        25        25
      3      1   13        1     Pre-Mask        NA        25
      4      1   14        1    Post-Mask        NA        25
      5      1   NA        1     Response        NA        25
      6      2    4        0     RedPrime        NA        20
      7      2    9        0 CircleTarget        20        20
      8      2   13        0     Pre-Mask        NA        20
      9      2   14        0    Post-Mask        NA        20
      10     2   NA        0     Response        NA        20
      
      merge[merge$Label =='Response',]$Code <- merge[merge$Label =='Response',]$newCode.y
      
         Trial Code Accuracy        Label newCode.x newCode.y
      1      1    6        1    BluePrime        NA        25
      2      1   12        1  SqureTarget        25        25
      3      1   13        1     Pre-Mask        NA        25
      4      1   14        1    Post-Mask        NA        25
      5      1   25        1     Response        NA        25
      6      2    4        0     RedPrime        NA        20
      7      2    9        0 CircleTarget        20        20
      8      2   13        0     Pre-Mask        NA        20
      9      2   14        0    Post-Mask        NA        20
      10     2   20        0     Response        NA        20
      

      抱歉没有用case when,希望你能用。

      【讨论】:

      • 当您多次使用merge 函数时,使用merge 作为数据框名称会使这个答案有点难以追踪。我建议为数据框使用不同的名称,也许是result
      猜你喜欢
      • 2019-05-28
      • 1970-01-01
      • 2021-01-19
      • 2015-03-29
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多