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

时间:2021-11-01 09:12:10

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.

简介:如何将m行添加到我的m X n数据框中,其中每个新行都插入每个现有行之后?我将基本上复制现有行,但对一个变量进行更改。

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.

更多细节:在提到另一个问题时,我想我可以用rgl的segments3d函数做我想做的事。我有一组x,y,z点,但这些只是一组线段的一个终点。另一个终点在Z维度上距离很远,作为第四个变量:X,Y,Z,Z_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:

根据rgl文档,“Points由seg3d成对拍摄”。因此,我认为我需要修改我的数据框,以便每隔一行使用一个改变的Z变量(通过从Z减去Z_Length)获得额外的条目。在视觉上,它需要从这个:

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

链接问题的数据样本可用。

5 个解决方案

#1


8  

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


5  

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:

我不确定rgl是如何在这里发挥作用的,但是如果你只想创建一个带有重复值的新data.frame,请尝试:

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

#3


2  

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:

编辑:完全解决e4e5f4的出色响应:

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


2  

modified from "e4e5f4's" response

修改自“e4e5f4”的回复

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


0  

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

#1


8  

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


5  

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:

我不确定rgl是如何在这里发挥作用的,但是如果你只想创建一个带有重复值的新data.frame,请尝试:

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

#3


2  

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:

编辑:完全解决e4e5f4的出色响应:

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


2  

modified from "e4e5f4's" response

修改自“e4e5f4”的回复

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


0  

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