循环以创建带有新列的数据框,然后将它们组合在一起

时间:2019-09-06 00:38:20

标签: r loops

我想在不同的飞行高度级别上复制我的数据集。我可以手动创建具有不同高度级别的数据框,然后将它们绑定在一起。但是,我想通过涉及一个for循环来使其更快?

这是示例数据集:

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

我是这样手动编码的:

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, .........)

我需要每100米执行一次,直到高度5100米。

5 个答案:

答案 0 :(得分:2)

这可以完全通过cbind完成,因为原始数据的行将重复:

cbind(dat, alt=rep(seq(100,5100,100), each=nrow(dat)))

这应该比遍历值快得多。

答案 1 :(得分:1)

考虑交叉联接merge

expanded_df <- merge(df, data.frame(alt=seq(100, 5100, 100)), by = NULL)

答案 2 :(得分:0)

创建一个序列,使用lapply对其进行循环transform以添加新列,然后使用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
#....

使用tidyverse

library(dplyr)
library(purrr)

map_df(seq(100, 5100, 100), ~df %>% mutate(alt = .x))

答案 3 :(得分:0)

我们可以使用crossing包中的tidyr

library(dplyr)
library(tidyr)

df2 <- crossing(df, tibble(alt = seq(100, 5100, 100)))

如果顺序很重要,请创建一个ID列,对其进行排列,然后将其删除。

df3 <- df %>%
  mutate(ID = 1:n()) %>%
  crossing(tibble(alt = seq(100, 5100, 100))) %>%
  arrange(alt, ID) %>%
  select(-ID)

答案 4 :(得分:0)

基于data.table的另一种(快速)替代方法是

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