0

This is not the same as R pairwise product.

Consider the following:

df <- structure(list(V1 = 10.3333333333333, V2 = 1.66666666666667, 
    V3 = 8.66666666666667, V4 = 2.66666666666667, V5 = 8.76666666666667, 
    V6 = 2, V7 = 6.33333333333333, V8 = 1.66666666666667, V9 = 11, 
    V10 = 2.66666666666667, V11 = 4.33333333333333, V12 = 1.66666666666667, 
    V13 = 9.83333333333333, V14 = 3.33333333333333), class = "data.frame", .Names = c("V1", 
"V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", 
"V12", "V13", "V14"), row.names = c(NA, -1L))

If we were treating this as a vector V, I would like to compute a vector consisting of the elements V[i] * V[i+1] for i = 1, 3, 5, ...., 13. (i.e., the first component is the product of the first two components of df, the second component is the product of the third and fourth components of df, etc.)

That is, the following produces the desired output:

> v <- numeric(7)
> df <- structure(list(V1 = 10.3333333333333, V2 = 1.66666666666667, 
+     V3 = 8.66666666666667, V4 = 2.66666666666667, V5 = 8.76666666666667, 
+     V6 = 2, V7 = 6.33333333333333, V8 = 1.66666666666667, V9 = 11, 
+     V10 = 2.66666666666667, V11 = 4.33333333333333, V12 = 1.66666666666667, 
+     V13 = 9.83333333333333, V14 = 3.33333333333333), class = "data.frame", .Names = c("V1", 
+ "V2", "V3", "V4", "V5", "V6", "V7", "V8", "V9", "V10", "V11", 
+ "V12", "V13", "V14"), row.names = c(NA, -1L))
> for (i in 1:length(v)){
+     v[i] <- df[1,2*i-1] * df[1,2*i]
+ }
> v
[1] 17.222222 23.111111 17.533333 10.555556 29.333333  7.222222 32.777778 

Is there a way to do this without a loop?

Clarinetist
  • 1,097
  • 18
  • 46

2 Answers2

1

This gives you literally what you asked for, given a data.frame with only one row:

v <- as.numeric(df[, seq(1, ncol(df), by=2)] * df[, seq(2, ncol(df), by=2)])

Leave out as.numeric to keep the result as a data.frame. This would work rowwise on a data.frame with more rows and would throw an error if the data.frame had an odd number of variables.

If that row of numbers were just a vector V as you called it, the principle is the same.

V <- unlist(df, recursive = TRUE, use.names = FALSE)
v <- V[seq(1, length(V), by=2)] * V[seq(2, length(V), by=2)]
ngm
  • 2,539
  • 8
  • 18
1

You can also use dplyr's lag/lead functions. For example:

library(dplyr)
(df*lag(df))[,seq(2,length(df),2)]
David Klotz
  • 2,401
  • 1
  • 7
  • 16