使用具有多个条件的 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 找到了多个元素,但只会使用第一个。
您可以通过使用 tidyverse
和 mutate
并将 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 创建
我有一个看起来像这样的数据框测验
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 找到了多个元素,但只会使用第一个。
您可以通过使用 tidyverse
和 mutate
并将 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 创建