R 根据多种条件更改变量的优雅方式?
我试图根据多种情况改变变量“曝光” 例如:如果刺激内容为“neg”,如果条件为“neg”,如果设置为“A”,那么对于刺激内容为X1、X2、。。。或X5。对于刺激号为X6、X7……或X10的线,变量“曝光”应改为“短” 我希望下面的代码能让问题更清楚 首先,这是近似数据集:R 根据多种条件更改变量的优雅方式?,r,loops,for-loop,if-statement,case-when,R,Loops,For Loop,If Statement,Case When,我试图根据多种情况改变变量“曝光” 例如:如果刺激内容为“neg”,如果条件为“neg”,如果设置为“A”,那么对于刺激内容为X1、X2、。。。或X5。对于刺激号为X6、X7……或X10的线,变量“曝光”应改为“短” 我希望下面的代码能让问题更清楚 首先,这是近似数据集: n <- 6 dataset <- data.frame( participant = rep(1:n, each=40), condition = rep(c("pos","neg&
n <- 6
dataset <- data.frame(
participant = rep(1:n, each=40),
condition = rep(c("pos","neg"), each=40),
set = rep(c("A","B"), each=40),
stimulus_content = rep(c("pos","neg"), each=2),
stimulus_no = rep(c("X1","X10","X11","X12","X13","X14","X15","X16","X17","X18","X19","X2","X20","X3","X4","X5","X6","X7","X8","X9"), each=2),
exposure = NA)
接下来,我们尝试了通过mutate和case_when。这段代码完全符合它的要求,但它几乎有100行长!请查看下面的摘录
longdat2 <- longdat %>%
mutate(exposure = case_when(
# Condition pos, set A
stimulus_no=="X1" & stimulus_content=="pos" & condition=="pos" & set=="A" ~ "long",
stimulus_no=="X2" & stimulus_content=="pos" & condition=="pos" & set=="A" ~ "long",
# ...
stimulus_no=="X9" & stimulus_content=="pos" & condition=="pos" & set=="A" ~ "short",
stimulus_no=="X10" & stimulus_content=="pos" & condition=="pos" & set=="A" ~ "short",
stimulus_no=="X11" & stimulus_content=="pos" & condition=="pos" & set=="A" ~ "none",
# ... accordingly for condition pos and set B, and for condition neg and set A
# and eventually for condition neg and set B
stimulus_no=="X18" & stimulus_content=="neg" & condition=="neg" & set=="B" ~ "short",
stimulus_no=="X19" & stimulus_content=="neg" & condition=="neg" & set=="B" ~ "short",
stimulus_no=="X20" & stimulus_content=="neg" & condition=="neg" & set=="B" ~ "short",
)
)
longdat2%
变异(暴露=情况)(
#条件位置,设置A
刺激物编号==“X1”&刺激物内容==“pos”&条件==“pos”&集合==“A”~“long”,
刺激物编号==“X2”&刺激物内容==“pos”&条件==“pos”&集合==“A”~“long”,
# ...
刺激物编号==“X9”&刺激物内容==“pos”&条件==“pos”&集合==“A”~“short”,
刺激物编号==“X10”&刺激物内容==“pos”&条件==“pos”&集合==“A”~“short”,
刺激物编号==“X11”&刺激物内容==“pos”&条件==“pos”&集合==“A”~“无”,
#…相应地,对于条件pos和设置B,对于条件neg和设置A
#最终条件为负,设置为B
刺激物编号==“X18”&刺激物内容==“neg”&条件==“neg”&集合==“B”~“短”,
刺激物编号==“X19”&刺激物内容==“neg”&条件==“neg”&集合==“B”~“短”,
刺激物编号==“X20”&刺激物内容==“neg”&条件==“neg”&集合==“B”~“短”,
)
)
如果有人能在循环中发现错误,或者能告诉我第二个(或第一个)选项的更简洁版本,我将非常感激
非常感谢!您可以使用%中的
%运算符和其他部分的反向条件简化第二个解决方案:
dataset2 <- dataset %>%
mutate(exposure = case_when(
# Condition pos, set A
(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X1","X2","X3","X4","X5") ~ "long",
(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X6","X7","X8","X9","X10") ~ "short",
(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X11","X12","X13","X14","X15","X16","X17","X18","X19","X20") ~ "none",
# else
!(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X11","X12","X13","X14","X15") ~ "long",
!(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X16","X17","X18","X19","X20") ~ "short",
!(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X1","X2","X3","X4","X5","X6","X7","X8","X9","X10") ~ "none"
)
)
dataset2%
变异(暴露=情况)(
#条件位置,设置A
(刺激内容==“位置”&条件==“位置”&设置==“A”)&刺激编号%c(“X1”、“X2”、“X3”、“X4”、“X5”)~“长”,
(刺激内容==“位置”&条件==“位置”&设置==“A”)&刺激编号%c(“X6”、“X7”、“X8”、“X9”、“X10”)~“短”,
(刺激内容==“位置”&条件=“位置”&设置=“A”)&刺激编号%c(“X11”、“X12”、“X13”、“X14”、“X15”、“X16”、“X17”、“X18”、“X19”、“X20”)~“无”,
#否则
!(刺激内容==“位置”&条件==“位置”&设置==“A”)&刺激编号%c(“X11”、“X12”、“X13”、“X14”、“X15”)~“长”,
!(刺激内容==“位置”&条件==“位置”&设置==“A”)&刺激编号%c(“X16”、“X17”、“X18”、“X19”、“X20”)~“短”,
!(刺激内容==“位置”&条件=“位置”&设置=“A”)&刺激编号%c(“X1”、“X2”、“X3”、“X4”、“X5”、“X6”、“X7”、“X8”、“X9”、“X10”)~“无”
)
)
编辑
对于具有循环的解决方案:
dataset3 <- dataset
for (i in 1:length(dataset3[,1])){
if(dataset3[i,"stimulus_content"] == "pos" & dataset3[i,"condition"] == "pos" & dataset3[i,"set"] == "A") {
if(dataset3[i,"stimulus_no"] %in% c("X1","X2","X3","X4","X5")) {dataset3[i,"exposure"] <- "long"}
if(dataset3[i,"stimulus_no"] %in% c("X6","X7","X8","X9","X10")) {dataset3[i,"exposure"] <- "short"}
if(dataset3[i,"stimulus_no"] %in% c("X11","X12","X13","X14","X15","X16","X17","X18","X19","X20")){dataset3[i,"exposure"] <- "none"}
} else {
if(dataset3[i,"stimulus_no"] %in% c("X11","X12","X13","X14","X15")) {dataset3[i,"exposure"] <- "long"}
if(dataset3[i,"stimulus_no"] %in% c("X16","X17","X18","X19","X20")) {dataset3[i,"exposure"] <- "short"}
if(dataset3[i,"stimulus_no"] %in% c("X1","X2","X3","X4","X5","X6","X7","X8","X9","X10")) {dataset3[i,"exposure"] <- "none"}
}
}
compareDF::compare_df(dataset3, dataset2, rownames)
#> Error in stop_or_warn("The two data frames are the same!", stop_on_error): The two data frames are the same!
dataset3您可以使用%
运算符中的%和其他部分的反向条件简化第二个解决方案:
dataset2 <- dataset %>%
mutate(exposure = case_when(
# Condition pos, set A
(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X1","X2","X3","X4","X5") ~ "long",
(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X6","X7","X8","X9","X10") ~ "short",
(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X11","X12","X13","X14","X15","X16","X17","X18","X19","X20") ~ "none",
# else
!(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X11","X12","X13","X14","X15") ~ "long",
!(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X16","X17","X18","X19","X20") ~ "short",
!(stimulus_content=="pos" & condition=="pos" & set=="A") & stimulus_no %in% c("X1","X2","X3","X4","X5","X6","X7","X8","X9","X10") ~ "none"
)
)
dataset2%
变异(暴露=情况)(
#条件位置,设置A
(刺激内容==“位置”&条件==“位置”&设置==“A”)&刺激编号%c(“X1”、“X2”、“X3”、“X4”、“X5”)~“长”,
(刺激内容==“位置”&条件==“位置”&设置==“A”)&刺激编号%c(“X6”、“X7”、“X8”、“X9”、“X10”)~“短”,
(刺激内容==“位置”&条件=“位置”&设置=“A”)&刺激编号%c(“X11”、“X12”、“X13”、“X14”、“X15”、“X16”、“X17”、“X18”、“X19”、“X20”)~“无”,
#否则
!(刺激内容==“位置”&条件==“位置”&设置==“A”)&刺激编号%c(“X11”、“X12”、“X13”、“X14”、“X15”)~“长”,
!(刺激内容==“位置”&条件==“位置”&设置==“A”)&刺激编号%c(“X16”、“X17”、“X18”、“X19”、“X20”)~“短”,
!(刺激内容==“位置”&条件=“位置”&设置=“A”)&刺激编号%c(“X1”、“X2”、“X3”、“X4”、“X5”、“X6”、“X7”、“X8”、“X9”、“X10”)~“无”
)
)
编辑
对于具有循环的解决方案:
dataset3 <- dataset
for (i in 1:length(dataset3[,1])){
if(dataset3[i,"stimulus_content"] == "pos" & dataset3[i,"condition"] == "pos" & dataset3[i,"set"] == "A") {
if(dataset3[i,"stimulus_no"] %in% c("X1","X2","X3","X4","X5")) {dataset3[i,"exposure"] <- "long"}
if(dataset3[i,"stimulus_no"] %in% c("X6","X7","X8","X9","X10")) {dataset3[i,"exposure"] <- "short"}
if(dataset3[i,"stimulus_no"] %in% c("X11","X12","X13","X14","X15","X16","X17","X18","X19","X20")){dataset3[i,"exposure"] <- "none"}
} else {
if(dataset3[i,"stimulus_no"] %in% c("X11","X12","X13","X14","X15")) {dataset3[i,"exposure"] <- "long"}
if(dataset3[i,"stimulus_no"] %in% c("X16","X17","X18","X19","X20")) {dataset3[i,"exposure"] <- "short"}
if(dataset3[i,"stimulus_no"] %in% c("X1","X2","X3","X4","X5","X6","X7","X8","X9","X10")) {dataset3[i,"exposure"] <- "none"}
}
}
compareDF::compare_df(dataset3, dataset2, rownames)
#> Error in stop_or_warn("The two data frames are the same!", stop_on_error): The two data frames are the same!
dataset31)grep创建一个由要匹配的列组成的code
粘贴在一起,然后使用正则表达式来匹配这些列以获得简洁的表达式。不使用任何包。请注意,[^a]将匹配非a的任何单个字符。如果只有a和B,则可以使用B。X1[1-5]将匹配X11,…,X15.X[6-9]| X10将匹配X6,…,X10.$匹配字符串的结尾。省略code1)grep创建一个code
,由要匹配的列粘贴在一起,然后使用正则表达式匹配它们以获得简明表达式。不使用包。请注意[^a]将匹配非A的任何单个字符。如果只有A和B,则可以使用B。X1[1-5]将匹配X11,…,X15.X[6-9]| X10将匹配X6,…,X10。$匹配字符串的结尾。省略代码这是什么语言?R?作为标记非常有用。比and或and两者都有用。对于(c(“X1”、“X2”、“X3”、“X4”、“X5”)中的刺激号){longdat[i,“exposure”]==“long”}
这看起来是错误的。这不应该是longdat[i,“exposure”]=“long”
或longdat[i,“exposure”]吗同样,循环体不使用循环变量(stimultium\u no
)我不确定循环应该做什么。如果它应该根据一组值检查一个值,那么在一个条件中需要一个contains
函数或in
操作符,而不是一个循环来多次执行它的主体。在第一个解决方案中有两个级别的循环。正如@knittl所说,应该用一个条件替换第二个级别n在
运算符中用替换:stimultium\u no
为longdat[i,“stimultium\u no”]
:如果(longdat[i,“stimultium\u no”]%在%c中(“X1”,“X2”,“X3”,“X4”,“X5”){longdat[i”,“exposure”]),这是什么语言?R?作为t真的有用吗
dataset5 <- within(dataset, {
# Condition pos, set A
exposure <- ifelse((stimulus_content == "pos" & condition == "pos" & set == "A") & stimulus_no %in% c("X1","X2","X3","X4","X5"), "long", exposure)
exposure <- ifelse((stimulus_content == "pos" & condition == "pos" & set == "A") & stimulus_no %in% c("X6","X7","X8","X9","X10"), "short", exposure)
exposure <- ifelse((stimulus_content == "pos" & condition == "pos" & set == "A") & stimulus_no %in% c("X11","X12","X13","X14","X15","X16","X17","X18","X19","X20"), "none", exposure)
# else
exposure <- ifelse(!(stimulus_content == "pos" & condition == "pos" & set == "A") & stimulus_no %in% c("X11","X12","X13","X14","X15"), "long", exposure)
exposure <- ifelse(!(stimulus_content == "pos" & condition == "pos" & set == "A") & stimulus_no %in% c("X16","X17","X18","X19","X20"), "short", exposure)
exposure <- ifelse(!(stimulus_content == "pos" & condition == "pos" & set == "A") & stimulus_no %in% c("X1","X2","X3","X4","X5","X6","X7","X8","X9","X10"), "none", exposure)
})
compareDF::compare_df(dataset5, dataset2, rownames)
#> Error in stop_or_warn("The two data frames are the same!", stop_on_error): The two data frames are the same!
dataset2 <- within(dataset, {
code <- paste(stimulus_content, condition, set, stimulus_no)
exposure[grep("pos pos A X[1-5]$", code)] <- "long"
exposure[grep("pos pos A (X[6-9]|X10)$", code)] <- "short"
exposure[grep("pos pos A (X1[1-9]|X20)$", code)] <- "none"
exposure[grep("pos pos [^A] X1[1-5]$", code)] <- "long"
exposure[grep("pos pos [^A] (X1[6-9]|X20)$", code)] <- "short"
exposure[grep("pos pos [^A] (X[1-9]|X10)$", code)] <- "none"
code <- NULL
})
Between <- function(x, lo, hi, alpha = "X") {
nonno <- gsub("\\d", "", x)
no = as.numeric(gsub("\\D", "", x))
no >= lo & no <= hi & nonno == alpha
}
dataset3 <- within(dataset, {
cond1 <- stimulus_content == "pos" & condition == "pos" & set == "A"
exposure[cond1 & Between(stimulus_no, 1, 5)] <- "long"
exposure[cond1 & Between(stimulus_no, 6, 10)] <- "short"
exposure[cond1 & Between(stimulus_no, 11, 20)] <- "none"
cond2 <- stimulus_content == "pos" & condition == "pos" & set != "A"
exposure[cond2 & Between(stimulus_no, 11, 15)] <- "long"
exposure[cond2 & Between(stimulus_no, 16, 20)] <- "short"
exposure[cond2 & Between(stimulus_no, 1, 10)] <- "none"
cond1 <- cond2 <- NULL
})