我是一个新的R用户,我一直在尝试执行嵌套在for循环中的if语句,以便编写新的变量。我有一个data.frame,其中一些人以前忘记编写来自E-prime的“条件”变量(3个级别的因素:旧的,新的,诱惑)。该任务有两个阶段编码/检索(块1和2),两组图像(A和B)和一个唯一的Word ID。
所以我有这个:
phase <- rep(c("Block1", "Block2"), each = 7)
condition <- rep(NA, times = 14)
setAorB <- rep(c("A", "B"), times = c(9,5))
WordID <- c(23,34,56,76,45,88,99,23,34,56,76,45,100,105)
loris_data <- data.frame(phase,condition,setAorB,WordID)
给了我:
> loris_data
phase condition setAorB WordID
1 Block1 NA A 23
2 Block1 NA A 34
3 Block1 NA A 56
4 Block1 NA A 76
5 Block1 NA A 45
6 Block1 NA A 88
7 Block1 NA A 99
8 Block2 NA A 23
9 Block2 NA A 34
10 Block2 NA B 56
11 Block2 NA B 76
12 Block2 NA B 45
13 Block2 NA B 100
14 Block2 NA B 105
我想要实现的是:在检索(Block2)时,如果setAorB是“A”,则条件是“old”。我尝试过这个基本循环,但显然只适用于旧项目,因为它不会区分诱饵与新项目。
for(i in 1:length(loris_data$condition)) {
if(loris_data$setAorB[i] == "A") {
loris_data$condition[i] <-"old"}
else {
loris_data$condition[i] <- "new"
}
}
然后,我想说:如果setAorB是“B”并且Word ID与A相同(这意味着它是诱饵),那么条件是“诱惑”,否则如果setAorB是“B”但是它有一个独特的WordID,条件是“新”。
这将是预期的输出:
> loris_data
phase condition setAorB WordID
1 Block1 <NA> A 23
2 Block1 <NA> A 34
3 Block1 <NA> A 56
4 Block1 <NA> A 76
5 Block1 <NA> A 45
6 Block1 <NA> A 88
7 Block1 <NA> A 99
8 Block2 old A 23
9 Block2 old A 34
10 Block2 lure B 56
11 Block2 lure B 76
12 Block2 lure B 45
13 Block2 new B 100
14 Block2 new B 105
任何人都可以帮助我解决这个问题,因为我还在学习,而且我正在努力奋斗吗?
答案 0 :(得分:1)
使用data.table
快速而肮脏的解决方案:
library(data.table)
setDT(loris_data)
loris_data[, condition := ifelse(setAorB == "A", "old", "new")]
loris_data[phase != "Block2", condition := NA]
loris_data[phase == "Block2" & setAorB == "B" & WordID %in% loris_data[phase == "Block1", WordID], condition := "lure"]
答案 1 :(得分:0)
你尝试过ifelse方法吗? ifelse
是R中的内置函数,如果测试运行矢量化并给出确定的输出。例如:
loris_data$resutl <- ifelse(test = loris_data[, "condition"] == "A",
yes = "old",
no = "new")
但是,如果你想在no中嵌入另一个ifelse,那就完全没问题了! 如果有效,请告诉我。
答案 2 :(得分:0)
使用dplyr
的解决方案。 loris_data2
是最终输出。
library(dplyr)
loris_data2 <- loris_data %>%
group_by(WordID) %>%
mutate(WordID_count = row_number()) %>%
ungroup() %>%
mutate(condition = case_when(
phase %in% "Block2" & setAorB %in% "A" ~ "old",
phase %in% "Block2" & setAorB %in% "B" & WordID_count > 1 ~ "lure",
phase %in% "Block2" & setAorB %in% "B" & WordID_count == 1 ~ "new",
TRUE ~ NA_character_
)) %>%
select(-WordID_count)
loris_data2
# # A tibble: 14 x 4
# phase condition setAorB WordID
# <fctr> <chr> <fctr> <dbl>
# 1 Block1 <NA> A 23
# 2 Block1 <NA> A 34
# 3 Block1 <NA> A 56
# 4 Block1 <NA> A 76
# 5 Block1 <NA> A 45
# 6 Block1 <NA> A 88
# 7 Block1 <NA> A 99
# 8 Block2 old A 23
# 9 Block2 old A 34
# 10 Block2 lure B 56
# 11 Block2 lure B 76
# 12 Block2 lure B 45
# 13 Block2 new B 100
# 14 Block2 new B 105
<强>解释强>
我的解决方案首先创建一个名为WordID_count
的新列,该列显示WordID
的外观时间。此任务通过以下方式实现。
loris_data %>%
group_by(WordID) %>%
mutate(WordID_count = row_number()) %>%
ungroup()
# # A tibble: 14 x 5
# phase condition setAorB WordID WordID_count
# <fctr> <lgl> <fctr> <dbl> <int>
# 1 Block1 NA A 23 1
# 2 Block1 NA A 34 1
# 3 Block1 NA A 56 1
# 4 Block1 NA A 76 1
# 5 Block1 NA A 45 1
# 6 Block1 NA A 88 1
# 7 Block1 NA A 99 1
# 8 Block2 NA A 23 2
# 9 Block2 NA A 34 2
# 10 Block2 NA B 56 2
# 11 Block2 NA B 76 2
# 12 Block2 NA B 45 2
# 13 Block2 NA B 100 1
# 14 Block2 NA B 105 1
之后,就可以填写condition
列了。此任务通过以下方式实现。
mutate(condition = case_when(
phase %in% "Block2" & setAorB %in% "A" ~ "old",
phase %in% "Block2" & setAorB %in% "B" & WordID_count > 1 ~ "lure",
phase %in% "Block2" & setAorB %in% "B" & WordID_count == 1 ~ "new",
TRUE ~ NA_character_
))
mutate
是创建或更新新列的功能。 case_when
是多个ifelse
语句的替代方案。该代码完成了以下工作:
如果phase
匹配Block2
且setAorB
匹配A
,则conditon
为old
。
如果phase
匹配Block2
且setAorB
匹配A
且WordID_count
大于1,则conditon
为{{ 1}}。
如果lure
匹配phase
且Block2
匹配setAorB
且A
大于1,则WordID_count
为{{ 1}}。
如果没有上述情况,则条件应为conditon
。
代码的最后一部分是new
,它只删除了NA
列,因为它不是原始数据框的一部分。