How can I add rows to an R data frame every other row?

巧了我就是萌 提交于 2020-03-11 13:21:18

问题


Brief: how can I add m rows to my m X n data frame, where each new row is inserted after each existing row? I will essentially copy the existing row, but make a change to one variable.

More detail: in reference to another question, I think I can do what I want with rgl's segments3d function. I have a set of x,y,z points, but these are just one end point of a set of line segments. The other end point is so many metres away in the Z dimension, given as a fourth variable: X,Y,Z,Z_Length; in my terminology it's easting,northing,elevation,length.

According to the rgl docs, "Points are taken in pairs by segments3d". So, I think I need to modify my data frame to have extra entries every second line with an altered Z variable (by subtracting Z_Length from Z). Visually, it needs to go from this:

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

to this:

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

A data sample at the linked question is available.


回答1:


Your sample data:

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)

Create your data to be inserted:

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

Append it to your original data:

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

Reorder the rows:

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



回答2:


I am not sure how rgl comes into play here, but if you just want to create a new data.frame with repeated values, try:

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



回答3:


Here's one possible approach if I understand what you're doing:

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: totally working off e4e5f4's excellent response:

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

Both are equivalent but I assume the alter is way faster.




回答4:


modified from "e4e5f4's" response

Insert blank rows betweens rows

    # 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 ;)



回答5:


You could create a new matrix with twice as many rows, put the old data frame elements back into the appropriate positions of the new matrix, and leave the gaps. Perform the calculations on elevation, creating a new matrix, then insert the adjusted elevation matrix into the larger, new matrix. Then convert the matrix back to a data frame.

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)`


来源:https://stackoverflow.com/questions/16453452/how-can-i-add-rows-to-an-r-data-frame-every-other-row

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!