我正在处理R
中的一些数据。我的数据框DF
看起来像这样(我在最后一面添加dput()
版本):
ID S.2014.01.01 S.2014.01.02 S.2014.01.03 S.2014.01.04
1 001 1 10 5 74
2 002 2 15 6 75
3 003 3 23 7 76
4 004 4 31 8 77
5 005 5 39 9 78
6 006 6 47 10 79
7 007 7 55 11 80
8 008 8 63 12 81
9 009 9 71 13 82
10 010 10 79 14 83
DF
包含一个ID变量和许多用日来解释数值的列(在本例中我只包含4个变量,实际数据帧在此样式中有超过100个变量)。我的目标是计算每对变量之间的差异。例如,我想计算变量S.2014.01.02
和S.2014.01.01
之间的差异,然后将值保存在名为D.2014.01.02
的新变量中。对于下一个变量,它是相同的过程。下一个案例是S.2014.01.03
和S.2014.01.02
,然后创建一个名为D.2014.01.03
的新列。
由于我的实际数据帧中的列数,我尝试了不同的解决方案。一种解决方案是逐个计算但不是最优的。此外,我尝试使用mutate_each()
包中的dplyr
函数,但我不知道如何设置成对列,然后创建新列。此外,我尝试使用同一个包中的lag()
函数,但它不起作用。我之所以使用这个函数,是因为我不仅需要计算列对的差异,而且还需要区分例如每两个或三个列而不是一个(对)。我想得到一个像这样的数据框:
ID S.2014.01.01 S.2014.01.02 S.2014.01.03 S.2014.01.04 D.2014.01.02 D.2014.01.03 D.2014.01.04
1 001 1 10 5 74 9 -5 69
2 002 2 15 6 75 13 -9 69
3 003 3 23 7 76 20 -16 69
4 004 4 31 8 77 27 -23 69
5 005 5 39 9 78 34 -30 69
6 006 6 47 10 79 41 -37 69
7 007 7 55 11 80 48 -44 69
8 008 8 63 12 81 55 -51 69
9 009 9 71 13 82 62 -58 69
10 010 10 79 14 83 69 -65 69
在此数据框中,我们可以看到以D
开头的新变量,它们是列对的差异的结果。我可以给出一些关于这种情况的建议,两个变量会很棒,但是如果你能帮我找到差异的版本,那么每个2或3列都会很棒。 dput()
的{{1}}版本是下一个:
DF
感谢您的帮助!
答案 0 :(得分:3)
无需转置或使用任何矢量化功能。
DF <- cbind(DF, DF[,3:5] - DF[,2:4])
names(DF)[6: 8] = gsub("S", "D", names(DF)[6: 8])
答案 1 :(得分:2)
我使用基本功能执行了以下操作。首先,我删除了ID列并创建了一个临时数据框。使用它,我拿了两列并在sapply()
处理减法。将结果转换为数据框并使用gsub()
分配新的列名称。最后,我将原始数据DF和结果(即新的)与cbind()
### Remove ID column
temp <- DF[, -1]
### pick up two columns and handle subtraction
new <- data.frame(sapply(1:(length(names(temp))-1), function(x){
temp[, x+1] - temp[ , x]
}))
### Assign column names. Change S to D in the word initial position and remove
### the first element of the vector.
names(new) <- gsub(pattern = "^[A-Z]", replacement = "D", x = names(temp))[-1L]
### Combine the original DF and the results
cbind(DF, new)
ID S.2014.01.01 S.2014.01.02 S.2014.01.03 S.2014.01.04 D.2014.01.02 D.2014.01.03 D.2014.01.04
1 001 1 10 5 74 9 -5 69
2 002 2 15 6 75 13 -9 69
3 003 3 23 7 76 20 -16 69
4 004 4 31 8 77 27 -23 69
5 005 5 39 9 78 34 -30 69
6 006 6 47 10 79 41 -37 69
7 007 7 55 11 80 48 -44 69
8 008 8 63 12 81 55 -51 69
9 009 9 71 13 82 62 -58 69
10 010 10 79 14 83 69 -65 69
答案 2 :(得分:1)
这有效:
## apply will return data we want in rows, to transpose with t() ----
newDF <- t( apply(DF[,-1], 1, function(x){ diff(x) }) )
newDF <- data.frame(newDF)
## set names we want
names(newDF) <- gsub(names(DF[,-c(1:2)]), pattern = "S.", replacement = "D.")
## combine into 1 data frame
newDF <- cbind(DF, newDF)
newDF
ID S.2014.01.01 S.2014.01.02 S.2014.01.03 S.2014.01.04 D.2014.01.02 D.2014.01.03 D.2014.01.04
1 001 1 10 5 74 9 -5 69
2 002 2 15 6 75 13 -9 69
3 003 3 23 7 76 20 -16 69
4 004 4 31 8 77 27 -23 69
5 005 5 39 9 78 34 -30 69
6 006 6 47 10 79 41 -37 69
7 007 7 55 11 80 48 -44 69
8 008 8 63 12 81 55 -51 69
9 009 9 71 13 82 62 -58 69
10 010 10 79 14 83 69 -65 69
请注意,我刚看到@ jazzurro的答案也有效。我想我会离开我的,因为它略有不同。