首页 > 解决方案 > R:创建新列,其中一个与条件匹配的同一列中的值之间的差异

问题描述

我有一个包含以下列的数据框:Slot、Period、SortNumber 和 Value。实际上,这个数据框是从一些访问数据库中读取数据而创建的,我在比较字符串等方面做了一些工作......所以,我也使用 RODBC 和 stringr 包。这部分代码在 R 和 Power BI 中完美运行,因此,我没有在此处重现。这是我的最终数据框的示例:

dfAccess <- data.frame(Slot = c("X1", "X2", "X3", "X1", "X3","X1", "X2", "X3", "X2", "X3"), 
                       Period = c(1,1,1,2,2,1,1,1,2,2), 
                       SortNumber = c(1, 1, 1, 1,1,2,2,2,2,2), 
                       Value = c(9,5,7,9,5,6,4,8,2,1))

此数据帧在 SortNumber 1 中没有时段 2 的插槽 X2,在 SortNumber 2 中没有时段 2 的插槽 X1(它可以错过任何行)。从视觉上看,它意味着:

Slot     Period    SortNumber    Value    
=======================================
X1         1          1           9    
X2         1          1           5    
X3         1          1           7    
X1         2          1           9   
X3         2          1           5    
X1         1          2           6    
X2         1          2           4    
X3         1          2           8    
X2         2          2           2    
X3         2          2           1    

我想创建一个新列(DiffValue)来计算值和值之间的差异,其中 SortNumer 为 = 1(按 Slot 和 Period 分组)

问题是 Slot 和 Period 不一定对每个 SortNumber 都具有相同的值。在这种情况下,我想使用 0 作为默认值并计算每一行的差异。

我正在使用dplyr,并且当数据一致时,工作正常。否则,我会收到错误消息:"Column DiffValue must be length 1 (the group size), not 0"

  dfAccess <-dfAccess %>%
  group_by(Slot, Period) %>%
  mutate(DiffValue = Value - Value[SortNumber == 1] )

使用这些数据,我想看到的是:

Slot     Period    SortNumber    Value    DiffValue
=========================================================
X1         1          1           9            0
X2         1          1           5            0
X3         1          1           7            0
X1         2          1           9            0
X3         2          1           5            0
X1         1          2           6           -3
X2         1          2           4           -1
X3         1          2           8            1
X2         2          2           2           -2 ("0" - 2)
X3         2          2           1           -4

这是一种方法吗?

编辑:我修改了原始帖子的部分内容,因为 Sinh Nguyen 在数据中发现了一个问题,但我仍然无法计算差异。

谢谢!

标签: rdplyrpowerbi

解决方案


仍然不能完全确定您的数据集的性质以及您想要实现的目标。但这将解决错误,并且对于Slot+Period没有的一对,SortNumber==1它将自动0(Zero)用作默认值。

# Sample data set with one pair of Slot+Period that doesn't have any SortNumber==1
dfAccess <- data.frame(Slot = c("X1", "X2", "X3", "X1", "X2", "X3","X1", "X2", "X3","X1", "X2", "X3"), 
           Period = c(1,1,1,2,2,2,1,1,1,2,2,2), 
           SortNumber = c(1, 1, 2, 1,1,1,2,2,2,2,2,2), 
           Value = c(9,5,7,9,1,5,6,4,8,10,2,1))

# Your command will generate an error
dfAccess <-dfAccess %>%
      group_by(Slot, Period) %>%
      mutate(DiffValue = Value - Value[SortNumber == 1] )
# ​Error: Column `DiffValue` must be length 2 (the group size) or one, not 0

# This command will only take 1st value of SortNumber==1 in any pair Slot+Number
dfAccess %>%
    group_by(Slot, Period) %>%
    mutate(DiffValue = Value - first(Value[SortNumber==1], default=0)) %>%
    ungroup()

推荐阅读