【问题标题】:R iterate through data frame and add incremental values to a column based on condition遍历数据框并根据条件向列添加增量值
【发布时间】:2020-08-15 11:31:52
【问题描述】:

我有一个这样的数据框:

tdf <- structure(list(indx = c(1, 1, 1, 2, 2, 3, 3), group = c(1, 1, 
2, 1, 2, 1, 1)), .Names = c("indx", "group"), row.names = c(NA, 
-7L), class = "data.frame")

数据框如下所示:

   indx group
1    1     1
2    1     1
3    1     2
4    2     1
5    2     2
6    3     1
7    3     1

我想遍历组,并将第一个索引的组值保留为所需的输出

对于第一个之后 indx 值的每个增量,我想从前一个 indx 中添加组的最大值,并希望从第二个城市开始增加组值。

想要的输出是这样的:

    indx group    desiredOutput
1    1     1             1
2    1     1             1
3    1     2             2
4    2     1             3
5    2     2             4
6    3     1             5
7    3     1             5

为了清楚起见,我将数据框拆分如下:

    indx group    desiredOutput
1    1     1             1
2    1     1             1       To be retained as is
3    1     2             2


4    2     1             3       Second index-the max value of desiredOutput in indx1 is 2                   
5    2     2             4       I want to add this max value to the group value in indx 2       


6    3     1             5       Similarly, the max value of des.out of indx2 is 4
7    3     1             5       Adding the max value to group provides me new values

我尝试将这个数据框拆分成一个数据框列表并迭代到每个数据框。

ndf <- split(tdf,f = tdf$indx)
x <- 0
for (i in seq_along(ndf)){
    ndf[[i]]$ng <- ndf[[i]]$group+x
    x <- max(ndf[[i]]$indx) + 1
}
ndf

上面的代码更新了第二个索引的值,但是当它到达第三个索引时失败了。

【问题讨论】:

    标签: r


    【解决方案1】:

    首先,找到每个索引的最大组值,然后计算这些组的累积总和。

    library(dplyr)
    
    maxGroupVals <- tdf %>% 
      group_by(indx) %>% 
      summarise(maxVal = max(group)) %>% 
      mutate(indx = indx + 1, maxVal = cumsum(maxVal))
    

    将 1 添加到索引,因为这是将添加这些最大值的索引。加入数据框将为您提供目标增加的列。然后它是一个简单的 mutate,带有一个条件语句来处理 index = 1 的情况。

    tdf %>% 
      left_join(maxGroupVals) %>% 
      mutate(desiredOutput = if_else(indx == 1, group, group + maxVal)) %>% 
      select(-maxVal)
    

    如果需要,删除中间计算列。

    【讨论】:

    • 谢谢....在我的主要数据集上完美工作。
    【解决方案2】:

    dplyr 1.0.1 版具有cur_group_id() 功能,它完全符合您的要求。在dplyr, the group_indices 的早期版本中,函数就是你想要的:

    library(dplyr)
    tdf %>% group_by(indx, group) %>%
      mutate(desiredOutput = cur_group_id()) %>%
      ungroup()
    

    【讨论】:

      【解决方案3】:

      考虑合并两列,然后转换为因子,然后转换为整数。因子水平由unique 设置,以避免按字母或数字排序,但在原始数据框中保留顺序。

      tdf <- within(tdf, {
          tmp <- paste(indx, group, sep="&")    
          new_indx <- as.integer(factor(tmp, levels=unique(tmp)))
          rm(tmp)    
      })
      
      tdf
      #   indx group new_indx
      # 1    1     1        1
      # 2    1     1        1
      # 3    1     2        2
      # 4    2     1        3
      # 5    2     2        4
      # 6    3     1        5
      # 7    3     1        5
      

      【讨论】:

      • 非常感谢。您的解决方案也有效。非常感谢使用 base r 的解决方案......从来不知道这些选项......让我思考。
      【解决方案4】:

      要获得唯一索引/组组合的运行计数,您可以简单地执行(在预先排序的数据上):

      tdf$desiredOutput <- cumsum(!duplicated(tdf))
      

      这给出了:

        indx group desiredOutput
      1    1     1             1
      2    1     1             1
      3    1     2             2
      4    2     1             3
      5    2     2             4
      6    3     1             5
      7    3     1             5
      

      【讨论】:

      • 非常感谢...您的解决方案也适用于给定的示例。我认为您的解决方案是最巧妙的解决方案……简直不敢相信这有多么简单……我尝试了 3-4 次,看看这是否在我更大的数据集上正常工作……它完美无瑕。再次感谢您。
      猜你喜欢
      • 2020-01-19
      • 2021-10-11
      • 2021-01-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-08
      • 2020-04-21
      • 2021-03-02
      • 1970-01-01
      相关资源
      最近更新 更多