R 如何进行双循环+;否则呢?
作为R方面的新手,我很难设置适当的代码(我仍然认为它必须包括if/else命令和循环) 具体来说,我想比较两条信息(参见简化示例,因为我的实际数据库相当长):“每月分类”和“参考分类”。要考虑的“Ref_category”仅在每个元素的第5个周期计算(因为接下来我们将移动到下一个元素),这要归功于模式公式,每个元素(元素_id)R 如何进行双循环+;否则呢?,r,R,作为R方面的新手,我很难设置适当的代码(我仍然认为它必须包括if/else命令和循环) 具体来说,我想比较两条信息(参见简化示例,因为我的实际数据库相当长):“每月分类”和“参考分类”。要考虑的“Ref_category”仅在每个元素的第5个周期计算(因为接下来我们将移动到下一个元素),这要归功于模式公式,每个元素(元素_id) Months元素\u Id每月\u类别参考\u类别预期\u输出 1 1 3 NA 0 2 1 2 NA 0 3 1 2 NA 1 4 1 NA 1 5 1
Months元素\u Id每月\u类别参考\u类别预期\u输出
1 1 3 NA 0
2 1 2 NA 0
3 1 2 NA 1
4 1 NA 1
5 1 3 3 0
1 2 6 2 0
2 2 6 6 1
3 2 NA 10
4 2 NA 6 0
5 2 1 1 0
首先,请看一下@John Coleman和我在评论中向您提出的问题,因为我的解决方案可能会根据您的请求而改变
无论如何,您不需要显式的for循环或显式的if-else来完成任务
在R中,您通常不希望直接编写任何for循环。你最好使用像lappy
这样的函数。在这种情况下,dplyr
包负责任何隐式循环
df <- tibble::tribble(~Months, ~Element_Id, ~Monthly_Category, ~Ref_Category, ~Expected_output,
1 , 1, 3, NA, 0,
2 , 1, 2, NA, 0,
3 , 1, 2, NA, 1,
4 , 1, 1, NA, 1,
5 , 1, 3, 3, 0,
1 , 2, 6, 2, 0,
2 , 2, 6, 6, 1,
3 , 2, 1, 1, 0,
4 , 2, 1, 6, 0,
5 , 2, 1, 1, 0)
library(dplyr)
library(purrr)
df %>%
# check if elements are equal
mutate(Real_Expected_output = !map2_lgl(Monthly_Category, Ref_Category, identical)) %>%
# sort by Element_Id and Months just in case your data is messy
arrange(Element_Id, Months) %>%
# For each Element_Id ...
group_by(Element_Id) %>%
# ... define your Expected Output
mutate(Real_Expected_output = as.integer(lag(Real_Expected_output, default = FALSE) &
lag(Real_Expected_output, 2, default = FALSE))) %>%
ungroup()
# Months Element_Id Monthly_Category Ref_Category Expected_output Real_Expected_output
# <dbl> <dbl> <dbl> <dbl> <dbl> <int>
# 1 1 3 NA 0 0
# 2 1 2 NA 0 0
# 3 1 2 NA 1 1
# 4 1 1 NA 1 1
# 5 1 3 3 0 1
# 1 2 6 2 0 0
# 2 2 6 6 1 0
# 3 2 1 1 0 0
# 4 2 1 6 0 0
# 5 2 1 1 0 0
编辑2:
我会根据你的要求再次编辑它。此时,我建议您创建一个外部函数来处理您的问题。看起来更干净
df <- tibble::tribble(~Months, ~Element_Id, ~Monthly_Category, ~Ref_Category, ~Expected_output,
1 , 1, 3, NA, 0,
2 , 1, 2, NA, 0,
3 , 1, 2, NA, 1,
4 , 1, 1, NA, 1,
5 , 1, 3, 3, 0,
1 , 2, 6, 2, 0,
2 , 2, 6, 6, 1,
3 , 2, NA, 1, 0,
4 , 2, NA, 6, 0,
5 , 2, 1, 1, 0)
library(dplyr)
library(purrr)
get_output <- function(mon, ref){
# set here your condition
exp <- !is.na(mon) & !map2_lgl(mon, last(ref), identical)
# check exp and lag(exp), then convert to integer
as.integer(exp & lag(exp, default = FALSE))
}
df %>%
# sort by Element_Id and Months just in case your data is messy
arrange(Element_Id, Months) %>%
# For each Element_Id ...
group_by(Element_Id) %>%
# ... launch your function
mutate(Real_Expected_output = get_output(Monthly_Category, Ref_Category)) %>%
ungroup()
# # A tibble: 10 x 6
# Months Element_Id Monthly_Category Ref_Category Expected_output Real_Expected_output
# <dbl> <dbl> <dbl> <dbl> <dbl> <int>
# 1 1 1 3 NA 0 0
# 2 2 1 2 NA 0 0
# 3 3 1 2 NA 1 1
# 4 4 1 1 NA 1 1
# 5 5 1 3 3 0 0
# 6 1 2 6 2 0 0
# 7 2 2 6 6 1 1
# 8 3 2 NA 1 0 0
# 9 4 2 NA 6 0 0
# 10 5 2 1 1 0 0
df%
# ... 启动你的功能
突变(实际预期产出=获取产出(每月类别、参考类别))%>%
解组()
##tibble:10 x 6
#月元素\u Id月\u类别参考\u类别预期\u输出实际\u预期\u输出
#
#1 11 3 NA 0 0
#2 2 1 2 NA 0 0
#3 3 1 2 NA 1 1
#4 4 1 NA 1 1
# 5 5 1 3 3 0 0
# 6 1 2 6 2 0 0
# 7 2 2 6 6 1 1
#832NA1000
#9 4 2 NA 6 0 0
# 10 5 2 1 1 0 0
“我仍然认为它必须包括if/else命令和循环”——这似乎是一个奇怪的要求。这是家庭作业问题陈述中的某种规定吗?循环在R中有它们的位置,但通常有更好的选择。“更准确地说,我想在“每月\u类别”与所选的“参考\u类别”在一行中有2个周期不同时(每5个观测值计算一次)输入1。否则,设置0。”那么为什么在第7行有1?这是元素_Id==2的第二个月:它应该是0。出于同样的原因,为什么第5行不等于1?首先,谢谢@Edo。为了更准确地回应您的评论,第5行等于0,因为对于元素n°1(元素id=1)的最后一个月观察:每月类别=参考类别(3=3,因此两个类别之间没有更多偏差,因此为0)。对于第7行:要素2的前两个月类别(第6行和第7行)为6,而要素2的参考类别(因此第10行)为1,因此偏差为1。然后,对于最后3行:每月类别=参考类别,因此我们有0(偏差结束)。事实上,对于每个元素(1个元素=5行),参考类别是在5个期间结束时使用模式计算的。然而,通过拉伸公式,我们在每行中都有值,而每次只考虑最后一个值(所以每5行)。这就是为什么我认为我们需要两个循环:一个循环检查每月类别的每一行,另一个循环检查每5行的参考类别。我应该在代码中更改什么以合并此功能?提前感谢Kay,我之前没有得到它,我不得不将每月分类
与最后一个参考分类
进行比较。首先,再次感谢您的帮助@Edo!然而,我还有最后一个问题。事实上,当我问这个问题时,我没有想过,但是:在我的“真实”数据库中,我有时会将“NA”作为每月类别的值。因此,对于代码,他认为NA与参考类别不同,并将1(逻辑)放在一起。当monthly category=NA时,我应该在代码中更改什么,然后它会自动变为0?因为最后,我只对值为1的行感兴趣,所以我希望NA也包含0。顺便说一句,我编辑了问题中的数据。谢谢好的,看看我的新编辑。不过,如果您有新问题,我认为您应该自己试一试。:-)
df <- tibble::tribble(~Months, ~Element_Id, ~Monthly_Category, ~Ref_Category, ~Expected_output,
1 , 1, 3, NA, 0,
2 , 1, 2, NA, 0,
3 , 1, 2, NA, 1,
4 , 1, 1, NA, 1,
5 , 1, 3, 3, 0,
1 , 2, 6, 2, 0,
2 , 2, 6, 6, 1,
3 , 2, NA, 1, 0,
4 , 2, NA, 6, 0,
5 , 2, 1, 1, 0)
library(dplyr)
library(purrr)
get_output <- function(mon, ref){
# set here your condition
exp <- !is.na(mon) & !map2_lgl(mon, last(ref), identical)
# check exp and lag(exp), then convert to integer
as.integer(exp & lag(exp, default = FALSE))
}
df %>%
# sort by Element_Id and Months just in case your data is messy
arrange(Element_Id, Months) %>%
# For each Element_Id ...
group_by(Element_Id) %>%
# ... launch your function
mutate(Real_Expected_output = get_output(Monthly_Category, Ref_Category)) %>%
ungroup()
# # A tibble: 10 x 6
# Months Element_Id Monthly_Category Ref_Category Expected_output Real_Expected_output
# <dbl> <dbl> <dbl> <dbl> <dbl> <int>
# 1 1 1 3 NA 0 0
# 2 2 1 2 NA 0 0
# 3 3 1 2 NA 1 1
# 4 4 1 1 NA 1 1
# 5 5 1 3 3 0 0
# 6 1 2 6 2 0 0
# 7 2 2 6 6 1 1
# 8 3 2 NA 1 0 0
# 9 4 2 NA 6 0 0
# 10 5 2 1 1 0 0