简体   繁体   中英

How to multiply EACH value from one row from a dataframe, with all values of a row from another datafrane

I have two data frames:

species = c ('A. alba', 'P. nigra', 'P.sylv', 'C. sativa', 'B. Pendula', 'Q. cerris', 'Q. petrae', 'Q. pubesc', 'P. alba', 'T. arvense')
speciesdat <- data.frame(pointID= species,matrix(runif(100),ncol=10,))

speciesdat

A. alba     0.43768279  0.70788388  0.22385977  0.4865352   0.65390645  0.6131476   0.9034217   0.9882588   0.045676450 0.1109551
P. nigra    0.23841748  0.10107243  0.31643354  0.9124586   0.17680009  0.5730999   0.3687399   0.6710573   0.424592606 0.9963007
P.sylv      0.03510202  0.66443096  0.56751081  0.2605511   0.27068835  0.3625468   0.6825015   0.6128847   0.394236153 0.9825921
C. sativa   0.83156640  0.87620244  0.28547281  0.6186353   0.03054993  0.6602586   0.7266206   0.5757858   0.044838758 0.9264902
B. Pendula  0.02853235  0.11147283  0.65968549  0.6087475   0.01859563  0.7705008   0.2588491   0.6160338   0.278875411 0.3760177
Q. cerris   0.33518206  0.66494652  0.44535126  0.6396948   0.84853701  0.8528920   0.9083867   0.3406821   0.301699912 0.7552817
Q. petrae   0.99028047  0.32606149  0.03991465  0.4070295   0.76723652  0.1510258   0.4583800   0.9209462   0.372419649 0.4774647
Q. pubesc   0.48350520  0.02714703  0.84217131  0.7785254   0.59770557  0.8242108   0.3781278   0.2444586   0.997081622 0.5707966
P. alba     0.32207762  0.17842972  0.72346310  0.2024601   0.04296549  0.7129133   0.7596528   0.1445458   0.009422524 0.9234416
T. arvense  0.46029757  0.72158301  0.35532973  0.8191271   0.85785606  0.1145541   0.7022644   0.9689575   0.524823767 0.9510237


veges = data.frame(pointID = species, matrix(runif(80), ncol=8))
veges

A. alba     0.8760049   0.08377138  0.7947616   0.15866494  0.94725913  0.4210001   0.75813441  0.03543249
P. nigra    0.5990935   0.26900508  0.6619769   0.02748618  0.06831557  0.0331052   0.74318637  0.48573950
P.sylv      0.7159880   0.84181724  0.6723000   0.52288279  0.17646907  0.7342308   0.32012234  0.12942797
C. sativa   0.1593788   0.41923564  0.6169959   0.87120304  0.51923185  0.7643932   0.15112887  0.38999869
B. Pendula  0.6589521   0.28458623  0.9378560   0.46504735  0.37802398  0.8599706   0.42625633  0.04834509
Q. cerris   0.6500326   0.33385627  0.7024338   0.11463147  0.95834461  0.9884738   0.67196514  0.47536082
Q. petrae   0.5767072   0.93077964  0.3999803   0.32463310  0.84351953  0.3218898   0.82015985  0.42689436
Q. pubesc   0.1727690   0.69179797  0.9994009   0.96287250  0.12937430  0.1530379   0.06389051  0.29790681
P. alba    0.7412723    0.74790322  0.6776089   0.92737920  0.44920139  0.9513559   0.84576046  0.22779249
T. arvense  0.6501236   0.05703468  0.2437144   0.13148191  0.40202796  0.8761405   0.53510479  0.86338306

The data frame speciesdat contains the possibility of species to exist in one cell.

What i want to do is to multiply for every species, each value of every cell from speciesdat , with the values from the veges , and create a new data frame which will contain this results.

How can i perform this calculation?

A smaller example:

species <- LETTERS[1:3]
speciesdat <- data.frame(pointID=species, matrix(1:9, ncol=3))
veges <- data.frame(pointID=species, matrix(10*(1:6), ncol=2))
speciesdat
##   pointID X1 X2 X3
## 1       A  1  4  7
## 2       B  2  5  8
## 3       C  3  6  9
veges
##   pointID X1 X2
## 1       A 10 40
## 2       B 20 50
## 3       C 30 60

outer can be used for this, with a bit of manipulation. This function will take a vector, split it in two, and return the outer product:

f <- function(x, len) { outer(x[seq(len)], x[-seq(len)])}

Here are the expanded columns, retrieved by calling the above function on the merged data:

m <- merge(speciesdat, veges, by='pointID')
t(apply(m[-1], 1, f, ncol(speciesdat)-1))

Adding back in the first column with cbind:

x <- cbind(m[1], t(apply(m[-1], 1, f, ncol(speciesdat)-1)))
x
##   pointID  1   2   3   4   5   6
## 1       A 10  40  70  40 160 280
## 2       B 40 100 160 100 250 400
## 3       C 90 180 270 180 360 540

To get the names as requested in the comment, compute with outer again:

n <- c('pointID',  outer(names(speciesdat[-1]), names(veges[-1]), FUN=paste, sep='-'))
n
## [1] "pointID" "X1-X1"   "X2-X1"   "X3-X1"   "X1-X2"   "X2-X2"   "X3-X2"  

These can be assigned the names of the structure above:

names(x) <- n

Note that the order is not as in your comment, but is correct for the operations in this example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM