我正在使用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 83DF包含一个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的新列。
由于实际数据帧中的列数不同,我尝试了不同的解决方案。一种解决方案是逐个计算,但不是最优的。此外,我还尝试使用dplyr包中的mutate_each()函数,但我不知道如何设置为获取成对的列,然后创建新的列。此外,我尝试使用同一个包中的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列的差异,那就太棒了。DF的dput()版本是下一个版本:
DF<-structure(list(ID = c("001", "002", "003", "004", "005", "006",
"007", "008", "009", "010"), S.2014.01.01 = c(1, 2, 3, 4, 5,
6, 7, 8, 9, 10), S.2014.01.02 = c(10, 15, 23, 31, 39, 47, 55,
63, 71, 79), S.2014.01.03 = c(5, 6, 7, 8, 9, 10, 11, 12, 13,
14), S.2014.01.04 = c(74, 75, 76, 77, 78, 79, 80, 81, 82, 83)), .Names = c("ID",
"S.2014.01.01", "S.2014.01.02", "S.2014.01.03", "S.2014.01.04"
), row.names = c(NA, -10L), class = "data.frame")谢谢你的帮忙!
发布于 2015-12-09 13:55:26
不需要转置或使用任何向量化函数。
DF <- cbind(DF, DF[,3:5] - DF[,2:4])
names(DF)[6: 8] = gsub("S", "D", names(DF)[6: 8])发布于 2015-12-09 12:26:17
我使用基本函数执行了以下操作。首先,我删除了ID列并创建了一个临时数据框。使用它,我获得了两列,并在sapply()中处理了减法。使用gsub()将结果转换为数据框并分配新的列名。最后,我使用cbind()将原始数据、DF和结果(即新数据)组合在一起
### 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发布于 2015-12-09 12:34:42
这是可行的:
## 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的答案,它也是有效的。我想我会把我的留在这里,因为它略有不同。
https://stackoverflow.com/questions/34170339
复制相似问题