2013-05-09 4 views
6

Краткое описание: как я могу добавить строки m в мой фрейм данных m X n, где каждая новая строка вставлена ​​после каждой существующей строки? Я по существу копирую существующую строку, но сделаю замену на одну переменную.Как добавить строки в кадр данных R каждую другую строку?

Подробнее: применительно к another question, я думаю, что могу делать то, что хочу, с помощью функции rgl segment3d. У меня есть набор точек x, y, z, но это всего лишь одна конечная точка набора сегментов линии. Другая конечная точка находится на расстоянии в несколько метров от размера Z, заданная как четвертая переменная: X, Y, Z, Z_Length; в моей терминологии это восток, север, высота, длина.

В соответствии с документами rgl «Точки принимаются парами по сегментам3d». Итак, мне кажется, мне нужно изменить свой фрейм данных, чтобы иметь дополнительные записи в каждой второй строке с измененной переменной Z (путем вычитания Z_Length из Z). Визуально, она должна идти от этого:

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

к этому:

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

Образец данных в связанном вопросе имеется.

ответ

8

Ваши данные выборки:

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) 

Создайте свои данные для ввода:

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

Append его к исходным данным:

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

Перегруппируйте строки:

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

Я думал, что мне нужно будет использовать что-то вроде своего решения, но кронекер - это не то, что я ожидал ... можете ли вы объяснить, как он делает то, что он делает? –

+2

Посмотрите, что «kronecker (1: 5, c (0,5),« + »)' дает вам. Для каждого элемента в первом векторе он добавляет ('FUN =" + "') все элементы во втором векторе, поэтому вы получаете: '1 + 0, 1 + 5, 2 + 0, 2 + 5 и т. Д. '. Конечно, есть другие способы получить этот вектор индексов, но я считаю это интересным. – flodel

+2

Это дико, мне это нравится. Ваш мозг работает замечательно. –

2

Вот один из возможных подходов, если я понимаю, что вы делаете:

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: полностью отработкой отличный ответ e4e5f4 в:

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

Оба эквивалентны, но я предполагаю, изменение происходит быстрее.

+0

(+1) для получения полного ответа.Я не заметил изменений, необходимых в колонке 4! – Nishanth

+1

Да, я пропустил это в свой первый раунд. –

0

Вы можете создать новую матрицу с вдвое большим количеством строк, вернуть старые элементы фрейма данных в соответствующие позиции новой матрицы и оставить пробелы. Выполните вычисления на высоте, создайте новую матрицу, затем вставьте скорректированную матрицу высот в большую новую матрицу. Затем преобразуйте матрицу обратно в кадр данных.

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

Я не знаю, как rgl вступает в игру, но если вы просто хотите, чтобы создать новый data.frame с повторяющимися значениями, попробуйте:

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

rgl, потому что первый черновик вопроса был обрамлен больше в сторону аспекта segment3d. Окончательный проект изменил его, чтобы быть более информационным кадром. Спасибо за ответ. –

+0

Что делает 1 в rep (..., 1, ...)? Кажется, что это нормально? – Xizam

2

редактировался "e4e5f4 годов" ответ

Вставка пустых строк Betweens строк

# 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 ;) 
Смежные вопросы