如何从前导行中的每前一行减去R中的每五行?

时间:2019-10-11 15:25:41

标签: r dataframe aggregate subtraction tapply

我有一个较大的数据框,其中包含多列和数千行。我想通过每五行数据框架从前导行中减去前一行的值来替换每个前导行的值。例如,第一个值应保留其值,第二行应为:<application .... android:usesCleartextTraffic="true"> 。同样,第六行应保留其值,但是第七行将为second row - first row。这是一个示例数据帧

seventh row - sixth row

输出量应如下所示

DF = data.frame(A= c(1:11), B = c(11:21))

3 个答案:

答案 0 :(得分:3)

f = function(d, n = 5) ave(d, ceiling(seq_along(d)/n), FUN = function(x) c(x[1], diff(x)))
data.frame(lapply(DF, f))
#    A  B
#1   1 11
#2   1  1
#3   1  1
#4   1  1
#5   1  1
#6   6 16
#7   1  1
#8   1  1
#9   1  1
#10  1  1
#11 11 21

另一种选择是创建具有移位行的另一个data.frame并直接减去

ind = ave(1:nrow(DF), ceiling(1:nrow(DF)/5), FUN = function(x) c(x[1], x[-length(x)]))
DF2 = DF[ind,] * replace(rep(1, nrow(DF)), diff(ind) == 0, 0)
DF - DF2

答案 1 :(得分:2)

一个选择是创建一个分组变量,然后使用diff进行转换,该转换将对mutate_all中所选列的相邻元素进行区别(如果仅需要一个列子集,使用mutate_ifmutate_at

library(dplyr) #v_0.8.3
DF %>% 
   group_by(grp = as.integer(gl(n(), 5, n()))) %>% 
   mutate_all(~c(first(.), diff(.))) %>%
   ungroup %>%
   select(-grp)
# A tibble: 11 x 2
#       A     B
#   <int> <int>
# 1     1    11
# 2     1     1
# 3     1     1
# 4     1     1
# 5     1     1
# 6     6    16
# 7     1     1
# 8     1     1
# 9     1     1
#10     1     1
#11    11    21

当我们在mutate_all之后使用group_by时,以上内容也给出了警告(以前它可以工作-在新版本中,正确的语法是使用mutate_at

DF %>% 
   group_by(grp = as.integer(gl(n(), 5, n()))) %>% 
   mutate_at(vars(-group_cols()), ~c(first(.), diff(.))) %>%
   ungroup %>%
   select(-grp)

答案 2 :(得分:2)

您可以%/%行号减去1乘5来获得组,然后使用diff获得与前一个x的差(如果没有前一个{ x中的{1}}),每个组的所有x列。

x

或者,如@akrun所述,您可以通过替换来避免library(data.table) setDT(DF) DF[, lapply(.SD, function(x) diff(c(0, x))) , (1:nrow(DF) - 1) %/% 5][, -1] # A B # 1: 1 11 # 2: 1 1 # 3: 1 1 # 4: 1 1 # 5: 1 1 # 6: 6 16 # 7: 1 1 # 8: 1 1 # 9: 1 1 # 10: 1 1 # 11: 11 21

lapply

lapply(.SD, function(x) diff(c(0, x)))

另一个不太严重的选择:

.SD - shift(.SD, fill = 0)