R 如何进行双循环+;否则呢?

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

作为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	          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