有rame raw_df如下:

library(tidyverse)

detail <- data.frame(cat = c("a","a","a","b","b","b","b","c","c"),
                     single_amount = c(1,3,7,2,1,4,6,1,6))
    
total <- data.frame(cat = c("a","b","c"),
                    total_amount = c(20,10,9))
    
raw_df <- detail %>% left_join(total, by = 'cat')

我定义了自功能allocate_data_m,以在cumsum(single_data)小于total_amount时分配total_amount

allocate_data_m <- function(data, single_data, total_data) {
  out <- cumsum_single_data <- rep('NA', nrow(data))
  for (grouprow in seq_len(nrow(data))) {
    
    cumsum_single_data[grouprow] <- 
      if_else(grouprow == 1, data[grouprow, single_data],
              cumsum_single_data[grouprow-1] + data[grouprow, single_data])
    
    out[grouprow] <- if_else(cumsum_single_data[grouprow] < data[grouprow, total_data], data[grouprow, single_data], 0)
  }
    out 
}

当在mutate中运行allocate_data_m时,会出现错误.有人可以帮忙吗?谢谢!

raw_df %>%
  group_by(cat) %>%
  mutate(amount_x_all = allocate_data_m(cur_data(), single_amount, total_amount))

愿望结果如下,我只是想知道allocate_data_m功能怎么就不能工作了.

raw_df %>%
  group_by(cat) %>%
  mutate(amount_x_all = if_else(cumsum(single_amount) < total_amount, single_amount, 0))

推荐答案

对您的功能的最小修改:

  1. "NA"替换为NA.前者是字面字符串,后者是指R中缺失的值.
  2. 将前ifelse()替换为if (...) {...} else {...}.否则,当grouprow为1时,cumsum_single_data[grouprow-1]会抛出错误.
  3. 将第二个ifelse()移至for循环之外,因为它可以进行向量化判断.
allocate_data_m <- function(single_data, total_data) {
  cumsum_single_data <- rep(NA, length(single_data))
  for (grouprow in seq_len(length(single_data))) {
    cumsum_single_data[grouprow] <- if(grouprow == 1) {
      single_data[grouprow]
    } else {
      cumsum_single_data[grouprow-1] + single_data[grouprow] 
    }
  }
  out <- ifelse(cumsum_single_data < total_data, single_data, 0)
  out 
}
raw_df %>%
  group_by(cat) %>%
  mutate(amount_x_all = allocate_data_m(single_amount, total_amount)) %>%
  ungroup()

# # A tibble: 9 × 4
#   cat   single_amount total_amount amount_x_all
#   <chr>         <dbl>        <dbl>        <dbl>
# 1 a                 1           20            1
# 2 a                 3           20            3
# 3 a                 7           20            7
# 4 b                 2           10            2
# 5 b                 1           10            1
# 6 b                 4           10            4
# 7 b                 6           10            0
# 8 c                 1            9            1
# 9 c                 6            9            6

版本 2

使用列名而不是列载体.在这种情况下,当您在mutate()内调用allocate_data_m()时,您必须使用带双引号的列名.

allocate_data_m <- function(data, single_data, total_data) {
  if(is(data, "tbl")) data <- as.data.frame(data)
  cumsum_single_data <- rep(NA, nrow(data))
  for (grouprow in seq_len(nrow(data))) {
    cumsum_single_data[grouprow] <- if(grouprow == 1) {
      data[grouprow, single_data]
    } else {
      cumsum_single_data[grouprow-1] + data[grouprow, single_data]   
    }
  }
  out <- ifelse(cumsum_single_data < data[, total_data], data[, single_data], 0)
  out
}

raw_df %>%
  group_by(cat) %>%
  mutate(amount_x_all = allocate_data_m(cur_data(), "single_amount", "total_amount")) %>%
  ungroup()

R相关问答推荐

当我们不知道确切的子集号时,在框架中对数据进行子集化

如何在球体上绘制轮廓线?

图片中令人惊讶的行为

从嵌套列表中智能提取线性模型系数

基于现有类创建类的打印方法(即,打印tibles更长时间)

如何计算R数据集中每个女性的子元素数量?

如何删除gggvenn与gggplot绘制的空白?

整数成随机顺序与约束R?

在for循环中转换rabrame

如何在R中对深度嵌套的tibbles中的非空连续行求和?

将. xlsx内容显示为HTML表

有效识别长载体中的高/低命中

如何对2个列表元素的所有组合进行操作?

如何在R中描绘#符号?

汇总数据帧中的复制列,保持行的唯一性

如何创建累加到现有列累计和的新列?

数据集上的R循环和存储模型系数

通过R:文件名未正确写入[已解决]将.nc文件转换和导出为.tif文件

为什么将负值向量提升到分数次方会得到NaN

如果满足条件,则替换列的前一个值和后续值