2013-05-09 3 views
6

Kurz: Wie kann ich m Zeilen zu meinem m X n Datenrahmen hinzufügen, wo jede neue Zeile nach jeder vorhandenen Zeile eingefügt wird? Ich werde im Wesentlichen die bestehende Zeile kopieren, aber eine Änderung an einer Variablen vornehmen.Wie kann ich jeder zweiten Zeile Zeilen zu einem R-Datenrahmen hinzufügen?

Mehr Details: in Bezug auf another question, ich denke, ich kann tun, was ich will mit rgls segments3d Funktion. Ich habe eine Menge von x, y, z Punkten, aber das sind nur ein Endpunkt einer Reihe von Liniensegmenten. Der andere Endpunkt ist in der Z-Dimension so viele Meter entfernt, dass er als vierte Variable gegeben ist: X, Y, Z, Z_Length; in meiner Terminologie ist es Ost, Nord, Höhe, Länge.

Laut der rgl docs, "Punkte werden paarweise von segments3d genommen". Also, ich denke, ich muss meinen Datenrahmen ändern, um zusätzliche Einträge jede zweite Zeile mit einer geänderten Z-Variable (durch Subtrahieren von Z_Length von Z) zu haben. Optisch muss es von diesem gehen:

+-------+---------+----------+-----------+---------+ 
| Label | easting | northing | elevation | length | 
+-------+---------+----------+-----------+---------+ 
| 47063 | 554952 | 5804714 | 32.68  | 619.25 | 
| 47311 | 492126 | 5730703 | 10.40  | 1773.00 | 
+-------+---------+----------+-----------+---------+ 

dazu:

+-------+---------+----------+-----------+---------+ 
| Label | easting | northing | elevation | length | 
+-------+---------+----------+-----------+---------+ 
| 47063 | 554952 | 5804714 | 32.68  | 619.25 | 
| 47063 | 554952 | 5804714 | -586.57 | 619.25 | 
| 47311 | 492126 | 5730703 | 10.40  | 1773.00 | 
| 47311 | 492126 | 5730703 | -1762.26 | 1773.00 | 
+-------+---------+----------+-----------+---------+ 

an der verknüpften Frage eine Datenprobe zur Verfügung steht.

Antwort

8

Ihre Beispieldaten:

orig.df <- read.table(text = " 
Label easting northing elevation length 
47063 554952 5804714 32.68 619.25 
47311 492126 5730703 10.40 1773.00", header = TRUE) 

Erstellen Sie Ihre einzufügenden Daten:

insert.df <- transform(orig.df, elevation = elevation - length) 

anhängen, um sie Ihren ursprünglichen Daten:

out.df <- rbind(orig.df, insert.df) 

die Zeilen neu anordnen:

n <- nrow(orig.df) 
out.df[kronecker(1:n, c(0, n), "+"), ] 
# Label easting northing elevation length 
# 1 47063 554952 5804714  32.68 619.25 
# 3 47063 554952 5804714 -586.57 619.25 
# 2 47311 492126 5730703  10.40 1773.00 
# 4 47311 492126 5730703 -1762.60 1773.00 
+0

Ich dachte, ich müsste eine Art von etwas in meiner Lösung verwenden, aber Kronecker ist nicht das, was ich erwartet habe ... können Sie erklären, wie es tut, was es tut? –

+2

Sehen Sie, was 'kronecker (1: 5, c (0,5)," + ") Ihnen gibt. Für jedes Element im ersten Vektor fügt es ('FUN =" + "') alle Elemente im zweiten Vektor hinzu, so erhalten Sie: '1 + 0, 1 + 5, 2 + 0, 2 + 5, usw. '. Es gibt sicherlich andere Möglichkeiten, diesen Vektor von Indizes zu erhalten, aber ich finde diesen interessant. – flodel

+2

Das ist wild, ich liebe es. Dein Gehirn arbeitet wunderbar. –

2

Hier ist ein möglicher Ansatz, wenn ich verstehe, was du tust:

dat <- head(CO2, 10) # fake data set 

L1 <- lapply(1:nrow(dat), function(i) { 
    dat2x <- dat[i, ] 
    dat2x[4] <- dat[i, 4] - dat[i, 5] 
    rbind(dat[i, ], dat2x) 
}) 
do.call(rbind, L1) 

EDIT: total e4e5f4 die hervorragende Resonanz Abarbeiten:

new <- dat[rep(1:nrow(dat),1,each=2),] 
new[c(F, T),4] <- dat[4] - dat[5] 

Beide sind gleichwertig, aber ich nehme an Der Alter ist viel schneller.

+0

(+1) für eine vollständige Antwort.Ich habe die Änderung in Spalte 4 nicht bemerkt! – Nishanth

+1

Ja, das habe ich auch bei meiner ersten Runde vermisst. –

0

Sie könnten eine neue Matrix mit doppelt so vielen Zeilen erstellen, die alten Datenrahmenelemente wieder an die entsprechenden Positionen der neuen Matrix setzen und die Lücken belassen. Führen Sie die Höhenberechnung durch, erstellen Sie eine neue Matrix und fügen Sie dann die angepasste Höhenmatrix in die größere, neue Matrix ein. Dann wandle die Matrix wieder in einen Datenrahmen um.

test <- matrix(1:9, ncol=3) 
ind <- (1:nrow(test)*2 - 1 # - 1 b/c you want to insert rows after, not before, existing rows 
test_new <- matrix(rep(NA, (nrow(test)*2*ncol(test))), ncol=ncol(test)) 
test_new[ind,] <- test 

test_elev <- test #create a new matrix that will have adjusted elevations 
test_elev[,2] <- test[,2] - test[,3] #e.g., test[,2] is the elevation column, and test[,3] is the length column 
test_new[ind+1,] <- test_elev #then put the new elevations into the new matrix 

#if you need it to be a data.frame() again, you can use `as.data.frame(test_new)` 
5

Ich bin nicht sicher, wie rgl ins Spiel kommt hier, aber wenn Sie nur einen neuen data.frame mit wiederholten Werten erstellen möchten, versuchen Sie:

df[rep(1:nrow(df),1,each=2),] 
+0

rgl, weil der erste Entwurf der Frage mehr in Richtung segments3d Aspekt gerahmt wurde. Der endgültige Entwurf änderte es, um eher eine Datenrahmenabfrage zu sein. Danke für die Antwort. –

+0

Was macht die 1 im rep (..., 1, ...)? Es scheint ohne es gut zu funktionieren? – Xizam

2

von "e4e5f4 der" Antwort modifizierte

einfügen leere Zeilen betweens Reihen

# sample matrix of df 
    old <-matrix(1:9, ncol=3) 

    # double all rows 
    new <- old[rep(1:nrow(old),1,each=2),] 

    # replace all duplicates with blank cells 
    new[c(seq(2, dim(new)[1], by=2)), ] <- "" 

    old # original 
    new # all ok ;) 
Verwandte Themen