2017-07-27 57 views
2

我正在尝试创建一个数据框(BOS.df),以便探究将在接收实际数据之前执行的未来分析的结构。在这种情况下,可以说有4家餐厅希望运行广告系列(“餐厅”变量)。广告系列将持续的天数为cmp.lngth。我需要随机数字来表示广告的收费标准(ra.num)。广告系列在StartDate上开始。最终,我希望通过每个餐厅的周期创建一个数据框,并通过添加行来为广告系列的每一天添加随机结算编号。通过迭代添加行创建数据框

#Create Data Placeholders 
set.seed(123) 
Restaurant <- c('B1', 'B2', 'B3', 'B4') 
cmp.lngth <- 42 
ra.num <- rnorm(cmp.lngth, mean = 100, sd = 10) 
StartDate <- as.Date("2017-07-14") 


BOS.df <- data.frame(matrix(NA, nrow =0, ncol = 3)) 
colnames(BOS.df) <- c("Restaurant", "Billings", "Date") 


for(i in 1:length(Restaurant)){ 
    for(z in 1:cmp.lngth){ 
    BOS.row <- c(as.character(Restaurant[i]),ra.num[z],StartDate + 
    cmp.lngth[z]-1) 
    BOS.df <- rbind(BOS.df, BOS.row) 
    } 
} 

我的代码现在无法正常工作。列名称不正确,并且数据没有正确放置(如果有的话)。输出结果如下:

X.B1. X.94.3952435344779. X.17402. 
1 B1 94.3952435344779 17402 
2 B1    <NA>  <NA> 
3 B1    <NA>  <NA> 
4 B1    <NA>  <NA> 
5 B1    <NA>  <NA> 
6 B1    <NA>  <NA> 

如何获得正确的输出?有没有比使用for循环更有效的方法?

+0

拼写错误'也无济于事。 'cmp.lngth [z]'没有意义,因为'cmp.lngth'是一个单一的数字,而不是一个矢量 - 你可能只需要'z'在这里。 –

+0

嘿,安德鲁。感谢您的反馈。拼写错误来自我将代码翻译成我的提交,以便它不是可以远程识别的。 –

回答

1

使用expand.grid:在`lenght(Restuarant的)

cmp.lngth <- 2 
StartDate <- as.Date("2017-07-14") 

set.seed(1) 
df1 <- data.frame(expand.grid(Restaurant, seq(cmp.lngth) + StartDate)) 
colnames(df1) <- c("Restaurant", "Date") 
df1$Billings <- rnorm(nrow(df1), mean = 100, sd = 10) 
df1 <- df1[ order(df1$Restaurant, df1$Date), ] 

df1 
# Restaurant  Date Billings 
# 1   B1 2017-07-15 93.73546 
# 5   B1 2017-07-16 103.29508 
# 2   B2 2017-07-15 101.83643 
# 6   B2 2017-07-16 91.79532 
# 3   B3 2017-07-15 91.64371 
# 7   B3 2017-07-16 104.87429 
# 4   B4 2017-07-15 115.95281 
# 8   B4 2017-07-16 107.38325 
+0

谢谢!我收到了一条错误消息,但我仍然得到我想要的输出。 错误: '错误为了(NULL,C(17362,17362,17362,17362,17363,17363,17363,: 参数1不是VECTOR' –

+0

工作正常,我从错误。我会在运行代码之前检查对象Restaurant的类,并且可以通过命名expand.grid()中的变量并摆脱对data.frame的调用来简化它:'df1 < - expand.grid (餐厅=餐厅,日期= seq(cmp.lngth)+ StartDate)' – atiretoo

+0

谢谢,atootoo!我经历了这些变化并加入了这些变化,我也检查了餐厅的类并将其从字符转换为因子。 –

0

你可以使用rbind,但这是另一种方法。
另外,数据帧的长度应该是cmp.lngth * length(Restaurant),而不是cmp.lngth。

#Create Data Placeholders 
set.seed(123) 
Restaurant <- c('B1', 'B2', 'B3', 'B4') 
cmp.lngth <- 42 
ra.num <- rnorm(cmp.lngth, mean = 100, sd = 10) 
StartDate <- as.Date("2017-07-14") 


BOS.df <- data.frame(matrix(NA, nrow = cmp.lngth*length(Restaurant), ncol = 3)) 
colnames(BOS.df) <- c("Restaurant", "Billings", "Date") 

count <- 1 
for(name in Restaurant){ 
    for(z in 1:cmp.lngth){ 
     BOS.row <- c(name, ra.num[z], as.character(StartDate + z - 1)) 
     BOS.df[count,] <- BOS.row 
     count <- count + 1 
    } 
} 

我也建议你看一下名为tidyverse的包,并用tibble代替数据框使用add_row。下面是一个示例代码:

library(tidyverse) 
BOS.tb <- tibble(Restaurant = character(), 
       Billings = numeric(), 
       Date = character()) 

for(name in Restaurant){ 
    for(z in 1:cmp.lngth){ 
     BOS.row <- c(name, ra.num[z], as.character(StartDate + z - 1)) 
     BOS.tb <- add_row(BOS.tb, 
          Restaurant = name, 
          Billings = ra.num[z], 
          Date = as.character(StartDate + z - 1)) 
    } 
}