2013-05-09 10 views
6

Krótka instrukcja: jak mogę dodać wiersze m do mojej ramki danych , gdzie każdy nowy wiersz jest wstawiany po każdym istniejącym wierszu? Zasadniczo skopiuję istniejący wiersz, ale zmienię jedną.Jak mogę dodać wiersze do ramki danych R co drugi rząd?

Więcej szczegółów: w odniesieniu do another question, myślę, że mogę zrobić to, co chcę z funkcją segmentów3d firmy rgl. Mam zestaw punktów x, y, z, ale to tylko jeden punkt końcowy zestawu segmentów linii. Drugi punkt końcowy jest tak wiele metrów dalej w wymiarze Z, podanym jako czwarta zmienna: X, Y, Z, Z_Length; w mojej terminologii jest to wschód, północ, elewacja, długość.

Według dokumentów rgl: "Punkty są parowane według segmentów3d". Tak więc, myślę, że muszę zmodyfikować moją ramkę danych, aby mieć dodatkowe wpisy co drugą linię ze zmienioną zmienną Z (odejmując Z_Length od Z). Wizualnie, musi iść z tego:

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

do tego:

+-------+---------+----------+-----------+---------+ 
| 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 | 
+-------+---------+----------+-----------+---------+ 

Próbka danych w połączonej pytanie jest dostępny.

Odpowiedz

8

Dane próbki:

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) 

Utwórz swoje dane do wstawienia:

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

dołączyć go do swojej pierwotnej danych:

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

Zmiana kolejności wierszy:

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

Pomyślałem, że będę musiał użyć jakiegoś rodzaju w moim rozwiązaniu, ale kronecker nie jest tym, czego się spodziewałem ... Czy możesz wyjaśnić, jak robi to, co robi? –

+2

Zobacz, co daje ci 'kronecker (1: 5, c (0,5)," + ")'. Dla każdego elementu w pierwszym wektorze dodaje ('FUN =" + "') wszystkie elementy w drugim wektorze, więc otrzymasz: '1 + 0, 1 + 5, 2 + 0, 2 + 5, itd. '. Z pewnością istnieją inne sposoby na uzyskanie tego wektora wskaźników, ale uważam, że jest to interesujące. – flodel

+2

To dzika, kocham to. Twój mózg działa cudownie. –

2

Oto jeden z możliwych podejść, czy rozumiem, co robisz:

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: całkowicie pracy off e4e5f4 za doskonałą odpowiedź:

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

Oba są równoważne ale zakładam zmiana jest o wiele szybsza.

+0

(+1) za udzielenie kompletnej odpowiedzi.Nie zauważyłem zmiany potrzebnej w kolumnie 4! – Nishanth

+1

Tak, ominąłem to również podczas mojej pierwszej rundy. –

0

Można utworzyć nową macierz z dwukrotnie większą liczbą wierszy, przywrócić stare elementy ramki danych do odpowiednich pozycji w nowej macierzy i pozostawić luki. Wykonaj obliczenia na elewacji, tworząc nową macierz, a następnie wstaw dopasowaną macierz elewacji do większej, nowej macierzy. Następnie przekonwertuj macierz z powrotem na ramkę danych.

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

nie jestem pewien, jak rgl grę wchodzi tutaj, ale jeśli chcesz po prostu stworzyć nową data.frame z powtarzających się wartości, spróbuj:

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

rgl, ponieważ pierwsze pytanie wstępne zostało sformułowane bardziej w kierunku aspektu segment3d. Ostateczna wersja robocza zmieniła ją tak, aby była bardziej zapytaniem o ramkę danych. Dziękuję za odpowiedź. –

+0

Co to jest 1 robienie w rep (..., 1, ...)? Wydaje się działać bez niego? – Xizam

2

modyfikowany "e4e5f4 tych" odpowiedź

Wstawianie pustych wierszy pośredników wiersze

# 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 ;) 
Powiązane problemy