使用具有多个条件的 if 语句来替换数据框 (R) 中的因素的问题

Problem using if statement with multiple conditions to substitute factors in dataframe (R)

我有一个看起来像这样的数据框测验

Participant  Group  Test  Marks
1             1      Qz1   2.4
1             1      Qz2   3.2
1             1      Qz3   2
1             1      Qz4   1
2             1      Qz1    3
2             1      Qz2   4
2             1      Qz3   3
2             1      Qz4   4
3             2      Qz1   4
3             2      Qz2   2
3             2      Qz3   3
3             2      Qz4   2

假设除测验 $Marks 之外的所有列都是因素。

我想创建另一个因子列 quiz$zip,使用如下内容:

if ((quiz$Group==1) & (quiz$Test=='Qz2'| quiz$Test == 'Qz4'))
     {quiz$zip<-3}
else if ((quiz$Group==1) & (quiz$Test=='Qz1'| quiz$Test == 'Qz3'))
     {quiz$zip<-2}
else
     {quiz$zip<-1}

我做不出来,除了深夜,我找不到其他原因。

非常感谢您的帮助和启发!

您可以使用嵌套 ifelse

transform(df, zip = factor(ifelse(Group == 1 & Test %in% c('Qz2', 'Qz4'), 1, 
                            ifelse(Group == 1 & Test %in% c('Qz1', 'Qz3'), 2, 3))))

case_when 来自 dplyr

library(dplyr)

df %>%
  mutate(zip = factor(case_when(Group == 1 & Test %in% c('Qz2', 'Qz4') ~ 1, 
                                Group == 1 & Test %in% c('Qz1', 'Qz3') ~ 2, 
                                TRUE ~ 3)))

#   Participant Group Test Marks zip
#1            1     1  Qz1   2.4   2
#2            1     1  Qz2   3.2   1
#3            1     1  Qz3   2.0   2
#4            1     1  Qz4   1.0   1
#5            2     1  Qz1   3.0   2
#6            2     1  Qz2   4.0   1
#7            2     1  Qz3   3.0   2
#8            2     1  Qz4   4.0   1
#9            3     2  Qz1   4.0   3
#10           3     2  Qz2   2.0   3
#11           3     2  Qz3   3.0   3
#12           3     2  Qz4   2.0   3

数据

df <- structure(list(Participant = structure(c(1L, 1L, 1L, 1L, 2L, 
2L, 2L, 2L, 3L, 3L, 3L, 3L), .Label = c("1", "2", "3"), class = "factor"), 
Group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L), .Label = c("1", "2"), class = "factor"), Test = structure(c(1L, 
2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("Qz1", 
"Qz2", "Qz3", "Qz4"), class = "factor"), Marks = c(2.4, 3.2, 
2, 1, 3, 4, 3, 4, 4, 2, 3, 2)), row.names = c(NA, -12L), class = "data.frame")

您应该已经看到类似 Bedingung hat Länge > 1 und nur das erste Element wird benutzt 的错误消息 - 可能是英文的。它说您的 if 找到了多个元素,但只会使用第一个。

您可以通过使用 tidyversemutate 并将 ifelse 循环放入其中轻松克服这个问题。通过 mutate,来自 ifelse 的指定将分配给条件为真的那些行的列。

您必须小心一点,因为第一个 ifelse 包含在第二个位置 - 将使用 FALSE 的值 - 第二个ifelse 条件。如果两个条件中的 none 都为真,我选择将 0 放入。

library(tidyverse)

quiz <- tribble(
  ~Participant, ~Group, ~Test, ~Marks,
    1,  1,  'Qz1',   2.4,
    1,  1,  'Qz2',   3,
    1,  1,  'Qz3',   2,
    1,  1,  'Qz4',   1,
    2,  1,  'Qz1',   3,
    2,  1,  'Qz2',   4,
    2,  1,  'Qz3',   3,
    2,  1,  'Qz4',   4,
    3,  2,  'Qz1',   4,
    3,  2,  'Qz2',   2,
    3,  2,  'Qz3',   3,
    3,  2,  'Qz4',   2
  )


quiz <- quiz %>% mutate(quiz = ifelse((quiz$Group == 1) & (quiz$Test == "Qz2" | quiz$Test == "Qz4"), 3,
  ifelse((quiz$Group == 1) & (quiz$Test == "Qz1" | quiz$Test == "Qz3"), 2, 0)
))
quiz
#> # A tibble: 12 x 5
#>    Participant Group Test  Marks  quiz
#>          <dbl> <dbl> <chr> <dbl> <dbl>
#>  1           1     1 Qz1     2.4     2
#>  2           1     1 Qz2     3       3
#>  3           1     1 Qz3     2       2
#>  4           1     1 Qz4     1       3
#>  5           2     1 Qz1     3       2
#>  6           2     1 Qz2     4       3
#>  7           2     1 Qz3     3       2
#>  8           2     1 Qz4     4       3
#>  9           3     2 Qz1     4       0
#> 10           3     2 Qz2     2       0
#> 11           3     2 Qz3     3       0
#> 12           3     2 Qz4     2       0

reprex package (v0.3.0)

于 2020-02-06 创建