How to multiply two unequal length vectors by a factor?

I have two data frames of different lengths. There is a unique factor that links two data frames together. I want to multiply the values ​​in a larger data frame by the match factor in a smaller data frame. Here is the code to demonstrate:

d1 <- data.frame(u = factor(x = LETTERS[1:5]), n1 = 1:5)
d2 <- data.frame(u = factor(x = rep(x = LETTERS[1:5], each = 2)), n2 = 1:10)

I want to d2[1:2, 2]multiply by d1[1, 2], because the coefficient "A" matches, etc. for other compliance factors.

+4
source share
3 answers

For this problem, you can also use one match, which should be somewhat more efficient than the / approach (especially if you don’t know, t need the data.frame file that is created last): mergetransform

d2$n2 * d1[match(d2$u, d1$u), 'n1']

# [1]  1  2  6  8 15 18 28 32 45 50
+3

merge , transform, .

> transform(merge(d1, d2), n.total = n1*n2)

   u n1 n2 n.total
1  A  1  1       1
2  A  1  2       2
3  B  2  3       6
4  B  2  4       8
5  C  3  5      15
6  C  3  6      18
7  D  4  7      28
8  D  4  8      32
9  E  5  9      45
10 E  5 10      50

, transform, with .

> with(merge(d1, d2), n1*n2)

 [1]  1  2  6  8 15 18 28 32 45 50

, , @jbaums, , merge .

> require(microbenchmark)
> microbenchmark(transform(merge(d1, d2), n.total = n1*n2),
+                with(merge(d1, d2), n1*n2),
+                d2$n2 * d1[match(d2$u, d1$u), 'n1'])

Unit: microseconds
                                        expr     min       lq       mean
 transform(merge(d1, d2), n.total = n1 * n2) 826.897 904.2275 1126.41204
                with(merge(d1, d2), n1 * n2) 658.295 722.6715  907.34581
         d2$n2 * d1[match(d2$u, d1$u), "n1"]  49.372  59.5830   78.42575
   median        uq      max neval cld
 940.3890 1087.0350 2695.521   100   c
 764.2965  934.5555 2463.300   100  b 
  66.2475   86.1505  260.820   100 a  
+3

, data.table ( jbaums, , )

library(data.table)
setkey(setDT(d1), u); setDT(d2)
d1[d2][, n.total := n1*n2][]
#     u n1 n2 n.total
#  1: A  1  1       1
#  2: A  1  2       2
#  3: B  2  3       6
#  4: B  2  4       8
#  5: C  3  5      15
#  6: C  3  6      18
#  7: D  4  7      28
#  8: D  4  8      32
#  9: E  5  9      45
# 10: E  5 10      50

( @Arun)

d2[d1, n2 := n2*n1] # Update (by reference) `n2`

d2[d1, new := n2*n1] # Add new column

. , n1

+2
source

All Articles