2016-12-23 9 views
1

Ich habe zwei Datenrahmen, die gemeinsame Spalten haben. Multipliziere zwei Datensätze und mehr in R

# Generate DF1 
    set.seed(219) 
    x0 <- rnorm(5, 22, 17) 
    x2 <- rnorm(5, 44, 15) 
    x3 <- rnorm(5, 56, 13) 
    x7 <- rnorm(5, 0, 3) 
    x9 <- rnorm(5, 28, 31) 
    x10 <- rnorm(5, 4, 75) 
    x11 <- rnorm(5, 7, 1) 
    dat1 <- data.frame(x0,x2,x3,x7,x9, x10, x11) 
    dat1$ID1 <- rownames(dat1) 

    # Generate DF2 
    x1 <- rnorm(10, 2, 19) 
    x2 <- rnorm(10, 4, 18) 
    x3 <- rnorm(10, 5, 17) 
    x4 <- rnorm(10, 7, 16) 
    x5 <- rnorm(10, 8, 51) 
    x6 <- rnorm(10, 9, 5) 
    x7 <- rnorm(10, 0, 3) 
    x8 <- rnorm(10, 34, 2) 
    x9 <- rnorm(10, 28, 1) 
    dat2 <- data.frame(x1,x2,x3,x4,x5,x6,x7,x8,x9) 
    dat2$ID2 <- rownames(dat2) 

anzumerken, dass DF1 hat 5 Reihen während DF2 10 Reihen hat. Ähnliche Spaltennamen in jedem Datenrahmen bedeuten auch nicht, dass beide Spalten den gleichen Wert haben. Diese

ist, was ich möchte tun:

  1. Da DF1 5 Reihen hat, ich brauche 5 Spalten in DF2 erstellen und nennen wir sie y1, y2, y3, y4, y5.

  2. Hier ist, wie y1 zu berechnen: Ich brauche die erste Zeile in DF1 zu nehmen und es mit ähnlichen Spalten in DF2 für alle Zeilen multiplizieren. Die Größe von y1 wird (10 Zeilen und 1 Spalte) sein. Und ich muss für jede Zeile in DF2 Folgendes berechnen.

    y1 = x0 + x2 (DF1) * x2 (DF2) + x3 (DF1) * x3 (DF2) + x7 (DF1) * x7 (DF2) + x9 (DF1) * x9 (DF2)

ähnlich Für y2, müssen wir in der zweiten Reihe von DF1 ... etc.

in Bezug auf Vektoren und Matrizen starten, ist hier, wie y1 zu berechnen.

Die erste Zeile in DF1 als (x01, x21, x31, x71, x91, x101, x111, ID11). Dann der erste erste Wert von y1 (erinnere dich, y1 ist 10 * 1):

y11 = x01 + x21 (DF1) * x21 (DF2) + x31 (DF1) * x31 (DF2) + x71 (DF1) * x71 (DF2) + x91 (DF1) · x91 (DF2).

Zweiter Wert von y1:

y12 = x01 + x21 (DF1) * x22 (DF2) + x31 (DF1) * x32 (DF2) + x71 (DF1) * x72 (DF2) + x91 (DF1) * x92 (DF2).

...

finaly, der 10. Wert von y1 ist:

Y110 = x01 + x21 (DF1) * x210 (DF2) + x31 (DF1) * X310 (DF2) + x71 (DF1) * x710 (DF2) + x91 (DF1) * x910 (DF2).

Wie kann ich meinen Algorithmus implementieren?

+0

So wird die 'x0' Konstante 'y2' sein 'Y3', etc .. das heißt, ob die Formel für 'y2' unterscheidet, 'Y3', usw. – akrun

+0

korrekt. da DF2 keine x0 .... hat, kann ich x0 in DF2 als 1e hinzufügen und dann x0 (DF1) * x0 (DF2). – user9292

+0

auch, noch ein Zweifel, so wird die erste Zeile für 'x2' in DF1 mit allen Zeilen von 'x2' in 'DF2' multipliziert werden? – akrun

Antwort

2

Dies basiert auf meinem Verständnis von dem, was Sie tun möchten, was ich in einem Kommentar angedeutet habe.

Grundsätzlich für die nicht gemeinsame Spalten aus dat1 ich sie durch einen Vektor von Einsen multipliziert sie in eine anpaßbare Dimension zu erhalten, addierte dann die 10x1 Vektoren für jeden y (y1 usw.) zeilenweise, so dass jeder Vektor ist ein 10x1:

common_cols <- intersect(colnames(dat1),colnames(dat2)) 
uniq_cols <- setdiff(colnames(dat1),colnames(dat2)) 
uniq_cols <- uniq_cols[!uniq_cols=="ID1"] 

tmp <- data.frame(y1=rep(NA,10), y2=rep(NA,10),y3=rep(NA,10),y4=rep(NA,10),y5=rep(NA,10)) 
tmp1 <- data.frame(matrix(nrow=10, ncol = 7)) 

for(i in 1:nrow(dat1)){ 
    for(j in 1:length(common_cols)){ 
    tmp1[,j] <- dat1[i,common_cols[j]] * dat2[,common_cols[j]] 
    } 
    for(k in 1:length(uniq_cols)){ 
    tmp1[,k+4] <- dat1[i,uniq_cols[k]]*rep(1,10) 
    } 
    tmp[,i] <- rowSums(tmp1) 
} 

Das Ergebnis ist:

tmp 
  y1   y2  y3  y4   y5 
1 2796.812 226.31244 1924.2130 4392.7841 1459.8979 
2 1786.241 17.11732 716.6079 2044.0003 141.6572 
3 1371.890 -334.09190 324.3946 1578.0200 -262.0858 
4 1235.717 -446.01583 176.2845 1422.1088 -411.2424 
5 1995.976 -377.33202 1152.6527 3297.5986 635.7040 
6 2233.255 197.51252 1155.2367 2847.4433 599.1098 
7 3437.539 1675.03212 2328.7100 3876.5423 1914.7753 
8 291.687 -1331.27575 -737.9568 299.7451 -1413.6779 
9 1659.648 -244.14992 678.3120 2266.3193 144.3870 
10 1675.775 -532.41657 668.3817 2491.0892 60.3962 
+0

Ich manuell y11 für die obigen Daten berechnet (gleiche Samen), aber ich habe 2744.334 (nicht 2796.812). Ich habe meine Frage bearbeitet, um die genauen Berechnungen für y1 zu zeigen. Vielen Dank. – user9292

+0

@ user9292 Können Sie durch die Logik schauen und mir sagen, wo Ihre Berechnung anders ist? Es sollte eine triviale Änderung sein, aber im Moment bin ich nicht sicher, wo die Logik sich unterscheidet. Wenn Sie es in R berechnet haben, können Sie den Code zu Ihrer Frage hinzufügen. –

+0

y11 <- 3,3448395 + (33,8937 * 54,5535477) + (66,85438 * -11,412676) + (-2,125617 * -2,7894739) + (56,797272 * 29,03353) = 2744,334. – user9292

0

Mit einem dplyr und tidyr Ansatz:

library(magrittr); library(dplyr) 

DF1 generieren

set.seed(219) 
x0 <- rnorm(5, 22, 17) 
x2 <- rnorm(5, 44, 15) 
x3 <- rnorm(5, 56, 13) 
x7 <- rnorm(5, 0, 3) 
x9 <- rnorm(5, 28, 31) 
x10 <- rnorm(5, 4, 75): i am commenting this out, based on your 
x11 <- rnorm(5, 7, 1): 
dat1 <- data.frame(x0,x2,x3,x7,x9, x10, x11) 
# dat1$ID1 <- rownames(dat1) : not yet 

generieren DF2

x1 <- rnorm(10, 2, 19) 
x2 <- rnorm(10, 4, 18) 
x3 <- rnorm(10, 5, 17) 
x4 <- rnorm(10, 7, 16) 
x5 <- rnorm(10, 8, 51) 
x6 <- rnorm(10, 9, 5) 
x7 <- rnorm(10, 0, 3) 
x8 <- rnorm(10, 34, 2) 
x9 <- rnorm(10, 28, 1) 
dat2 <- data.frame(x1,x2,x3,x4,x5,x6,x7,x8,x9) 
# dat2$ID2 <- rownames(dat2) : not yet 

die fehlenden Vars erstellen in dat2

dat2$x0 <- 1 
newCol <- names(dat1)[!(names(dat1) %in% names(dat2))] 
dat2[, names(dat1)[!(names(dat1) %in% names(dat2))]] <- 0 

Rownames Spalten

dat1$ID1 <- rownames(dat1) 
dat2$ID2 <- rownames(dat2) 

Form breit langen Tisch

df1 <- tidyr::gather(dat1, X, var, -c(ID1)) 
df2 <- tidyr::gather(dat2, X, var, -c(ID2)) 

kommen Sie mit den beiden Tabellen

df1 <- left_join(df1, df2, by="X") 
rm(df2) 

tun, um Ihre Vermehrung

df1$var <- df1$var.x * df1$var.y 

y Spalten erstellen

df1 %<>% group_by(ID1, ID2) %>% summarise(var=sum(var)) %>% ungroup %>% 
    mutate(ID1=paste0("y", ID1)) %>% 
    {left_join(dat2, tidyr::spread(., ID1, var), by="ID2")} 

halten relevanten Spalten

df1 <- df1[, names(df1)[!(names(df1) %in% newCol)]] 

View(df1) 
Verwandte Themen