我有一个数据帧(实际上我有170列(85对)和~8000行)
data <- data.frame(A = c(6,5,4,3), B = c(2,2,2,2), C = c(9,8,7,6), D = c(2,2,2,2))
对于所有行,我想从第1列,第3列第4列等中减去第2列。
我想我需要尝试编写函数或以某种方式使用apply。
R有一个矢量化操作来在一次调用中处理这种任务:
data[c(1,3)] - data[c(2,4)]
## or for every column until the end of the dataset
data[seq(1,ncol(data),2)] - data[seq(2,ncol(data),2)]
# A C
#1 4 7
#2 3 6
#3 2 5
#4 1 4
请参阅前面的讨论,了解许多有用的建议 - Selecting multiple odd or even columns/rows for dataframe
您可以对此进行扩展,以便自动完成命名:
s <- seq(1,ncol(data),2)
data[paste0(names(data[s]), "minus", names(data)[-s])] <- data[s] - data[-s]
data
# A B C D AminusB CminusD
#1 6 2 9 2 4 7
#2 5 2 8 2 3 6
#3 4 2 7 2 2 5
#4 3 2 6 2 1 4
您可以选择c(TRUE,FALSE)或其否定的每隔一列。 binary-minus有一个dataframe方法:
data[c(TRUE,FALSE)] - data[c(FALSE,TRUE)]
A C
1 4 7
2 3 6
3 2 5
4 1 4
如果你想命名然后有意义,你可以在名字上使用paste
:
paste( names(data[c(TRUE,FALSE)]) , "_minus_", names( data[c(FALSE,TRUE)]) )
data.frame
s上的许多基本操作都是矢量化的,这意味着加法,减法,乘法等是元素方面的。即以下作品:
data <- data.frame(A = c(6,5,4,3), B = c(2,2,2,2), C = c(9,8,7,6), D = c(2,2,2,2))
data$AminusB <- data$A - data$B
data$CminusD <- data$C - data$D
print(data)
# A B C D AminusB CminusD
#1 6 2 9 2 4 7
#2 5 2 8 2 3 6
#3 4 2 7 2 2 5
#4 3 2 6 2 1 4
您也可以访问第4列,例如data[4]
或data[,4]
或data[,"D"]
等。见help("[")
。根据您的输出方式,有多种选择。通过简单的for循环,您可以遍历列并实现所有差异。
拥有170列,指定每个列名称将是艰巨的。如果您的所有列都是数字,则可以执行以下操作:
#Sample data
set.seed(123)
df <- data.frame(x = floor(rnorm(5, 10, 2)),
y = floor(rnorm(5, 30, 2)),
z = floor(rnorm(5, 50, 2)))
x y z
1 8 33 52
2 9 30 50
3 13 27 50
4 10 28 50
5 10 29 48
减去列:
df[-1] - df[-ncol(df)]
y z
1 25 19
2 21 20
3 14 23
4 18 22
5 19 19
使用apply
的另一种方法:
-t(apply(data, 1, diff))[ , seq(1, ncol(data)-1, by=2)]
# B D
# [1,] 4 7
# [2,] 3 6
# [3,] 2 5
# [4,] 1 4