【问题标题】:how to avoid For loop to calculate new varaible by group如何避免 For 循环按组计算新变量
【发布时间】:2018-11-27 10:35:35
【问题描述】:

我希望这里有人可以帮助我。我正在尝试为我的工作学习 R 编码。

我一直在跟踪植物(称为生态型)的生长,它们用 Mock 或细菌 Xcc 处理。我有 2 个不同的实验(在不同的时间完成),在图像处理后我得到了区域。

我想计算每个生态型的 Normalized_Area = Area(t1)/Area(t0),对于每个实验 (Manip) 的每个处理,一次面积除以该生态型的面积 à bigining实验(t0)。每个植物在时间 0 有不同的面积,不同的实验有不同的开始时间。 (Normalized_Area 列中的预期结果示例)

请在下面找到我的 df 片段

    # A tibble: 24 x 6
   Manip Traitment Ecotype Date                 Area Normalized_Area
   <dbl> <chr>     <chr>   <dttm>              <dbl>           <dbl>
 1     1 mock      a1-2    2017-12-12 00:00:00 17699            1   
 2     1 mock      a1-2    2017-12-13 00:00:00 24538            1.39
 3     1 mock      a1-2    2017-12-14 00:00:00 27958            1.58
 4     1 xcc       a1-2    2017-12-12 00:00:00 19857            1   
 5     1 xcc       a1-2    2017-12-13 00:00:00 27973            1.41
 6     1 xcc       a1-2    2017-12-14 00:00:00 35875            1.81
 7     2 mock      a1-2    2018-03-20 00:00:00 18177            1   
 8     2 mock      a1-2    2018-03-21 00:00:00 20251            1.11
 9     2 mock      a1-2    2018-03-23 00:00:00 36679            2.02
10     2 xcc       a1-2    2018-03-20 00:00:00 17261            1   
11     2 xcc       a1-2    2018-03-21 00:00:00 18697            1.08
12     2 xcc       a1-2    2018-03-23 00:00:00 35345            2.05
13     1 mock      a1-10   2017-12-12 00:00:00 22853            1   
14     1 mock      a1-10   2017-12-13 00:00:00 34641            1.52
15     1 mock      a1-10   2017-12-14 00:00:00 40311            1.76
16     1 xcc       a1-10   2017-12-12 00:00:00 23754            1   
17     1 xcc       a1-10   2017-12-13 00:00:00 33247            1.40
18     1 xcc       a1-10   2017-12-14 00:00:00 40603            1.71
19     2 mock      a1-10   2018-03-20 00:00:00 28201            1   
20     2 mock      a1-10   2018-03-21 00:00:00 30306            1.07
21     2 mock      a1-10   2018-03-23 00:00:00 49086            1.74
22     2 xcc       a1-10   2018-03-20 00:00:00 27217            1   
23     2 xcc       a1-10   2018-03-21 00:00:00 29844            1.10
24     2 xcc       a1-10   2018-03-23 00:00:00 46540            1.71

我用 For 循环写了一段代码,但它引发了一些错误,我想用 dplyr 把它变成更易读的代码

date_debut=c("2017-12-12", "2018-03-20") # starting_time
data$Normalized_Area = NA   

for(manips in levels(as.factor(data$Manip))){     # for each manip      
   for(ecoty in levels(as.factor(data$Ecotype))){  # for each ecotype        
       for(traity in levels(as.factor(data$Traitement))){  # for each treatment           
           for( dd in levels(as.factor(date_debut))){    # for each level 
            tmp = subset(data,subset=c(Traitement==traity & Ecotype == ecoty & Manip == manips))  # creation d'un fichier tmp

            if(dim(tmp)[1] != 0){                                            
            #tmp = ordered(tmp$date[1:length(tmp$date-1)])

            # compute Area mean at D=0 for each Experiement 

                if(dd %in% as.character(tmp$Date)!=F){            
              A0 = tmp$Area[as.character(tmp$Date)== dd] # Select  A0 in                  tmp$Area corresponding to dd
              Norm_Area = tmp$Area /A0
              data$Normalized_Area[data$Traitement == traity & data$Ecotype== ecoty & data$Manip == manips] = Norm_Area 
            }
        }
      }
    }
  }

这是我的新代码的开始,但我卡住了

gpeData %>% 
    group_by(Traitement, Ecotype, Manip )  %>% 
    mutate_( Normalized_Area = Area / Area[wich(Date %in% date_debut)] ) 

有人知道怎么做吗?我为丑陋的代码道歉,但我独自学习 最好的

【问题讨论】:

  • 欢迎来到 SO。图片既不是代码也不是数据,除非主题是图像处理。而代码块是??????????并且问题的形成非常好,如果数据是实际数据(或代表性样本),它将帮助其他人帮助您。目标是有一个可重复的问题,以便人们可以做出可重复的答案。请点击您问题下方的“r”,然后点击“信息”并查看指南以及显着链接以了解如何正确发布数据。
  • 亲爱的 hrbrmstr 感谢您的评论。我在没有检查格式的情况下复制/粘贴了一段我的 csf 文件(对不起图片)。我希望我这次做得很好。

标签: r for-loop dplyr


【解决方案1】:

您非常接近必须自己解决问题。这是我的解决方案,我使用which.min从每个组中找到最早日期的索引,然后在计算中使用这个索引值。

gpeData<-structure(list(Manip = c(1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 
                                  2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), 
                        Traitment = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 
                                                2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L, 2L, 2L, 2L
                        ), .Label = c("mock", "xcc"), class = "factor"), Ecotype = structure(c(2L, 
                                                                                               2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 
                                                                                               1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("a1-10", "a1-2"
                                                                                               ), class = "factor"), Date = structure(c(1513036800, 1513123200, 
                                                                                                                                        1513209600, 1513036800, 1513123200, 1513209600, 1521504000, 
                                                                                                                                        1521590400, 1521763200, 1521504000, 1521590400, 1521763200, 
                                                                                                                                        1513036800, 1513123200, 1513209600, 1513036800, 1513123200, 
                                                                                                                                        1513209600, 1521504000, 1521590400, 1521763200, 1521504000, 
                                                                                                                                        1521590400, 1521763200), class = c("POSIXct", "POSIXt"), tzone = "GMT"), 
                        Area = c(17699L, 24538L, 27958L, 19857L, 27973L, 35875L, 
                                 18177L, 20251L, 36679L, 17261L, 18697L, 35345L, 22853L, 34641L, 
                                 40311L, 23754L, 33247L, 40603L, 28201L, 30306L, 49086L, 27217L, 
                                 29844L, 46540L), Normalized_Area = c(1, 1.39, 1.58, 1, 1.41, 
                                                                      1.81, 1, 1.11, 2.02, 1, 1.08, 2.05, 1, 1.52, 1.76, 1, 1.4, 
                                                                      1.71, 1, 1.07, 1.74, 1, 1.1, 1.71)), row.names = c(NA, -24L
                                                                      ), class = "data.frame")


library(dplyr)
ans<-gpeData %>% 
   group_by(Traitment, Ecotype, Manip )  %>% 
   mutate(NormArea=Area[which.min(Date)], Normalized= Area/NormArea)

【讨论】:

  • Dave2e 感谢您的回答。不幸的是,在我手中它并没有给出好的结果
  • 当我尝试在更大的数据集上使用它时,它与第一个生态类型相匹配,但看起来它使用始终相同的值(第一个即 17699)来执行比率。我试图发布一个示例,但我被审核了......
  • @Mehdi,参见上面的编辑,代码现在将规范化区域保存为自己的列,以便您可以看到正在使用的值。
  • 嗨 Dave2e,我用你的评论写了数据% 排列(Manip,Traitment, Ecotype, Date) %>% group_by(Traitment, Ecotype, Manip) %>% mutate (Normalized_Area=Area/Area[which(as.Date(Date)==min(as.Date(Date)))]] 。现在运行良好,非常感谢大家
猜你喜欢
  • 2016-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-21
  • 2014-10-21
相关资源
最近更新 更多