我有一个较大的数据框,其中包含多列和数千行。我想通过每五行数据框架从前导行中减去前一行的值来替换每个前导行的值。例如,第一个值应保留其值,第二行应为:<application
....
android:usesCleartextTraffic="true">
。同样,第六行应保留其值,但是第七行将为second row - first row
。这是一个示例数据帧
seventh row - sixth row
输出量应如下所示
DF = data.frame(A= c(1:11), B = c(11:21))
答案 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_if
或mutate_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)