从上一列中减去一列

时间:2018-03-29 09:28:30

标签: r apply cumsum

示例数据

dfData <- data.frame(ID = c(1, 2, 3, 4, 5), 
                  DistA = c(10, 8, 15, 22, 15), 
                 DistB = c(15, 35, 40, 33, 20),
                 DistC = c(20,40,50,45,30),
                 DistD = c(60,55,55,48,50))


   ID DistA DistB DistC DistD
 1  1    10    15    20    60
 2  2     8    35    40    55
 3  3    15    40    50    55
 4  4    22    33    45    48
 5  5    15    20    30    50

我有一些ID,其中有四列测量累积距离。我想创建一个新列,它给出每列的实际距离,即从上一列中减去下一列。 对于例如该表应如下所示:

       ID DistA DistB DistC DistD
   1   1    10     5    5     40
   2   2     8    27    5     15
   3   3    15    25    10    5
   4   4    22    11    12    3 
   5   5    15    5     10    20

更长的方法是

dfData$disA <- dfData$DistA
dfData$disB <- dfData$DistB - dfData$DistA
dfData$disC <- dfData$DistC - dfData$DistB
dfData$disD <- dfData$DistD - dfData$DistC

是否有更短的方法来执行此操作:

  apply(dfData,1,function(x) ???)

3 个答案:

答案 0 :(得分:3)

是的,您需要diff ...

dfData[,-c(1:2)] <- t(apply(dfData[,-1], 1, diff))

dfData
  ID DistA DistB DistC DistD
1  1    10     5     5    40
2  2     8    27     5    15
3  3    15    25    10     5
4  4    22    11    12     3
5  5    15     5    10    20

答案 1 :(得分:2)

我们可以使用矢量化选项

dfData[3:5] <- dfData[-(1:2)] -  dfData[-c(1, 5)]
dfData
#  ID DistA DistB DistC DistD
#1  1    10     5     5    40
#2  2     8    27     5    15
#3  3    15    25    10     5
#4  4    22    11    12     3
#5  5    15     5    10    20

如果更新的值用于顺序计算,则for循环将非常有用

nm1 <- names(dfData)[-1]
for(i in 1:3) dfData[[nm1[i+1]]] <- dfData[[nm1[i+1]]] - dfData[[nm1[i]]]

答案 2 :(得分:1)

一种简单的方法可以是:

dfData[3:5] = dfData[3:5] - dfData[(3:5) - 1]
#    ID DistA  DistB DistC DistD
# 1  1    10     5     5    40
# 2  2     8    27     5    15
# 3  3    15    25    10     5
# 4  4    22    11    12     3
# 5  5    15     5    10    20

与@akrun提供的一个选项非常相似。

相关问题