Reputation: 71
I want to duplicate my dataset on different flight altitude levels. I can do it manually creating dataframes with differing levels of altitude and then rbind them together. But, i want to make it faster by involving a for loop?
this is the example dataset:
structure(list(heading = c(0L, 71L, 132L, 143L, 78L, 125L, 0L,
171L, 165L, 159L), thermal = c(1.25823300871478, 1.2972715238927,
1.65348398199965, 2.04165937130312, 1.496194948775, 1.70668245624966,
1.32775326817617, 1.37003605552932, 1.85841102388127, 1.20642577473389
), WS = c(17.1590022110329, 7.60663206413036, 16.3515501561529,
15.8336908137001, 7.11013207359218, 8.69420768960291, 5.23228331387401,
10.2762569508197, 3.79321542059933, 4.80008774506314), trackId = structure(c(3L,
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("ke1601", "ke1607",
"mwb1501", "mwb1502", "mwb1503", "mwb1504", "nsm1605", "rcees17110",
"rcees17111", "X27230893", "X27231081", "X27233186", "X27234135",
"X52409530"), class = "factor")), row.names = c(NA, 10L), class = "data.frame")
I was coding manually like this:
msl100 <- df %>% mutate(alt = 100)
msl200 <- df %>% mutate(alt = 200)
msl300 <- df %>% mutate(alt = 300)
msl400 <- df %>% mutate(alt = 400)
msl500 <- df %>% mutate(alt = 500)
df1 <- rbind(msl100, .........)
I need to do this for every 100 meters up to height 5100 meters.
Upvotes: 0
Views: 74
Reputation: 50668
Another (fast) data.table
-based alternative would be to do
library(data.table)
setDT(df)[, .(alt = seq(100, 5100, 100)), by = names(df)]
# heading thermal WS trackId alt
# 1: 0 1.258233 17.159002 mwb1501 100
# 2: 0 1.258233 17.159002 mwb1501 200
# 3: 0 1.258233 17.159002 mwb1501 300
# 4: 0 1.258233 17.159002 mwb1501 400
# 5: 0 1.258233 17.159002 mwb1501 500
#---
#506: 159 1.206426 4.800088 mwb1501 4700
#507: 159 1.206426 4.800088 mwb1501 4800
#508: 159 1.206426 4.800088 mwb1501 4900
#509: 159 1.206426 4.800088 mwb1501 5000
#510: 159 1.206426 4.800088 mwb1501 5100
Upvotes: 0
Reputation: 93803
This can be done purely through a cbind
as the rows of the original data will repeat:
cbind(dat, alt=rep(seq(100,5100,100), each=nrow(dat)))
This should be much faster than looping over values.
Upvotes: 2
Reputation: 107567
Consider a cross join merge
:
expanded_df <- merge(df, data.frame(alt=seq(100, 5100, 100)), by = NULL)
Upvotes: 1
Reputation: 39154
We can use crossing
from the tidyr
package.
library(dplyr)
library(tidyr)
df2 <- crossing(df, tibble(alt = seq(100, 5100, 100)))
If the order is important, create an ID column, arrage it, and then delete it.
df3 <- df %>%
mutate(ID = 1:n()) %>%
crossing(tibble(alt = seq(100, 5100, 100))) %>%
arrange(alt, ID) %>%
select(-ID)
Upvotes: 0
Reputation: 388807
Create a sequence, use lapply
to loop over it transform
to add new column and rbind
do.call(rbind, lapply(seq(100, 5100, 100), function(x) transform(df, alt = x)))
# heading thermal WS trackId alt
#1 0 1.258233 17.159002 mwb1501 100
#2 71 1.297272 7.606632 mwb1501 100
#3 132 1.653484 16.351550 mwb1501 100
#4 143 2.041659 15.833691 mwb1501 100
#5 78 1.496195 7.110132 mwb1501 100
#6 125 1.706682 8.694208 mwb1501 100
#7 0 1.327753 5.232283 mwb1501 100
#8 171 1.370036 10.276257 mwb1501 100
#9 165 1.858411 3.793215 mwb1501 100
#10 159 1.206426 4.800088 mwb1501 100
#11 0 1.258233 17.159002 mwb1501 200
#12 71 1.297272 7.606632 mwb1501 200
#....
Using tidyverse
that would be
library(dplyr)
library(purrr)
map_df(seq(100, 5100, 100), ~df %>% mutate(alt = .x))
Upvotes: 0