R 中的列操作

Within column operations in R

我有一个看起来像这样的数据集:

dt<- data.table(group= c(1,1,2,2,3,3),
var1=c("a","b","c","c","c","a"),
              var2=c(100,150,150,120,80,100))
   group var1 var2
1:     1    a  100
2:     1    b  150
3:     2    c  150
4:     2    c  120
5:     3    c   80
6:     3    a  100

其中组变量表示观察值属于同一组。

我想在列中执行操作。

我想做两件事: 首先是创建一个指示变量,用于标识每个组中 var1 相同的观察结果。因此,例如,在示例数据集中,IDvar1 变量将为第 2 组取值 1,因为 var1 对于组中的两个观察值相同 (c)。

其次,创建一个变量来指示 var2 的组内差异。因此,例如第 1 组 diffvar2 将取值 50,假设 150-100=1.

最终数据集应如下所示。

   group var1 var2 IDvar1 diffvar2
1:     1    a  100      0       50
2:     1    b  150      0       50
3:     2    c  150      1      -30
4:     2    c  120      1      -30
5:     3    c   80      0       20
6:     3    a  100      0       20

关于如何以简洁高效的方式执行此操作的任何建议? 非常感谢!

按'group'分组,比较观察数(.N)是否不等于'var1'(uniqueN)的唯一观察数来创建'IDvar1',并获取 'var2' 的 difference 以创建 'diffvar2' 列

library(data.table)
dt[, c("IDvar1", "diffvar2") := .(+(uniqueN(var1) != .N), 
       diff(var2)[1]) , by = group]

-输出

> dt
   group   var1  var2 IDvar1 diffvar2
   <num> <char> <num>  <int>    <num>
1:     1      a   100      0       50
2:     1      b   150      0       50
3:     2      c   150      1      -30
4:     2      c   120      1      -30
5:     3      c    80      0       20
6:     3      a   100      0       20

@akrun 使用 data.table 给出了一个很好的答案,我认为 dplyr 解决方案也可能会受到欢迎(速度较慢,但​​可读性更强)。

library(dplyr)
df <- as_tibble(dt)

df <- df %>%
    group_by(group) %>%
    mutate(
        IDvar1 = if_else(length(unique(var1)) == 1, 1, 0), # if there is only one unique value of var1 within each group, IDvar1 is 1, else it is 0
        diffvar2 = diff(var2)[1]
    )

一般来说,我会小心 diff(),尤其是在分组时,因为如果每组没有正好两个观察值,这会立即中断。