从一行数据和列值创建多行数据

时间:2015-11-24 23:07:20

标签: r

我有一行数据,我希望根据值分为5行。

附件是我想要实现的形象。我不知道从哪里开始。费用在7天内平均分配。

更新: 我现在可以使用下面的代码执行此操作:但它给了我一个错误:

1)它添加了一个名为NA的最后一列 2)它将第一个Var中的所有值替换为NA

Source Data

enter image description here

`df<-read.csv("C:\\TEST1.CSV")

df1<-df[FALSE,];

#For every week
for (i in 1:dim(df)[1]){
  #For all seven days
  for (j in 1:7){
    df1<-rbind(df1,df[i,]/7);
  }
}

df2<-data.frame(seq(as.Date("2011-05-02"), as.Date("2015-11-22"), by="days"),df1);

colnames(df2)<-colnames(df)

write.csv(df2, file = "C:TEST1RES.CSV")`
发现

错误:  在输出文件中,变量的第一列,即col 3始终为NA。怎么会发生这种情况?

3 个答案:

答案 0 :(得分:4)

这是您可以尝试的一种解决方案。请注意,它可能不适用于有类似问题的其他人,因为它假定没有跳过日期。

<强> 1。您的数据。

为了演示,我将在R中重新创建一部分数据。

var woosToDo = {};
    window.indexedDB = window.indexedDB || window.webkitIndexedDB ||
                    window.mozIndexedDB;

    woosToDo.indexedDB = {};
    woosToDo.indexedDB.db = null;

    window.addEventListener("DOMContentLoaded", init, false);

    window.addEventListener('DOMContentLoaded', function () {
      document.getElementById("newitem").addEventListener("click", addTodo(), false);
    });

...
...

    function addTodo() {
      var todo = document.getElementById("todo");
      woosToDo.indexedDB.addTodo(todo.value);
      todo.value = "";
    }

<强> 2。复制行。

您可以使用rep功能复制行。

cost_a <- c(5, 6)
cost_b <- c(3, 4)
date <- c("2015-05-02", "2015-05-09")
df <- data.frame(date, cost_a, cost_b)

数字7表示您想要多少重复项(即重复6次)。 1:3表示第一到第三列。如果您有10列费用,那么它将是1:11。

第3。订购行

使用默认的rep命令不会按照您希望的方式对行进行排序,因此您可以按日期快速排序

df.expanded <- df[rep(row.names(df), 7), 1:3]

<强> 4。获取新值

你可以像这样划分7:

df.sorted <- df.expanded[order(df.expanded$date),]

<强> 5。制作新约会。

您可以使用seq命令自动创建日期列表。

df.divided <- df.sorted/7

假设没有跳过任何日期。输入我放置日期的地方的第一个和最后一个日期。如有必要,您还可以选择除日期之外的其他部门列出清单。

<强> 6。将新日期与分割值合并;

date <- seq(as.Date("2015-05-02"), as.Date("2015-05-15"), by="days")

现在使用:

df.divided$date <- date 

看看你是否得到了你想要的东西

答案 1 :(得分:2)

您可以使用简单的循环。通过使用[FALSE,]dim(df)[1],我的脚本将适应更大的尺寸。

#Your original dataset
df<-matrix(c(5,3,1,6,4,2),2,3);

#New dataset
df1<-df[FALSE,];

#For every week
for (i in 1:dim(df)[1]){
#For all seven days
  for (j in 1:7){
    df1<-rbind(df1,df[i,]/7);
  }
}

df2<-data.frame(seq(as.Date("2011-05-02"), as.Date("2011-05-15"), by="days"),df1);
colnames(df2)<-c("cal_day","cost a","cosy b","cost c")

如果您已加载数据集,则应使用:

colnames(df2)<-colnames(df)

结果如下:

df2;
      cal_day    cost a    cost b    cost c
1  2015-05-02 0.7142857 0.1428571 0.5714286
2  2015-05-03 0.7142857 0.1428571 0.5714286
3  2015-05-04 0.7142857 0.1428571 0.5714286
4  2015-05-05 0.7142857 0.1428571 0.5714286
5  2015-05-06 0.7142857 0.1428571 0.5714286
6  2015-05-07 0.7142857 0.1428571 0.5714286
7  2015-05-08 0.7142857 0.1428571 0.5714286
8  2015-05-09 0.4285714 0.8571429 0.2857143
9  2015-05-10 0.4285714 0.8571429 0.2857143
10 2015-05-11 0.4285714 0.8571429 0.2857143
11 2015-05-12 0.4285714 0.8571429 0.2857143
12 2015-05-13 0.4285714 0.8571429 0.2857143
13 2015-05-14 0.4285714 0.8571429 0.2857143
14 2015-05-15 0.4285714 0.8571429 0.2857143

编辑以回答新错误(阅读评论)

如果没有您的数据集,我无法解决您的错误。 但是,您的周数似乎比预期的要长。要拥有1666行,您需要238周。您在seq(...)中输入的日期甚至不能将结果整除为7.因此它们是错误的。原始数据集中的最后一个日期必须晚于&#34; 2015-08-31&#34;你放了!

如果您要尊重1666天(原始数据集中周数的7倍),那么将来自&#34; 2011-05-02&#34;到&#34; 2015-11-22&#34;。

length(seq(as.Date("2011-05-02"), as.Date("2015-11-22"), by="days"));

原来你说你有52周。这将产生364行。

您在我们无法解决的代码中犯了一个错误,因为我们看不到数据。只需查看原始数据集并尊重相同的日期即可。

编辑2:

你忘了摆脱第一列。显然,如果你不这样做,计算日期会产生新的。

请改用此代码:

df<-TEST1;
#Get rid of the first column
df1<-df[-1];


#New dataset
df2<-df1[FALSE,];


#For every week
for (i in 1:dim(df)[1]){
  #For all seven days
  for (j in 1:7){
    df2<-rbind(df2,df1[i,]/7);
  }
}

df3<-data.frame(seq(as.Date("2011-05-02"), as.Date("2011-05-15"), by="days"),df2);
colnames(df3)<-colnames(df);

head(df3);

答案 2 :(得分:2)

使用 data.table 包的替代解决方案:

library(data.table)
df <- setDT(df)[, .(dates = as.Date(date:(date+6), origin="1970-01-01"), 
                    cost_a = cost_a/7, 
                    cost_b = cost_b/7,
                    cost_c = cost_c/7), 
                by = date][, date:=NULL]

这给出了:

> df
         dates    cost_a    cost_b    cost_c
 1: 2015-05-02 0.7142857 0.4285714 0.1428571
 2: 2015-05-03 0.7142857 0.4285714 0.1428571
 3: 2015-05-04 0.7142857 0.4285714 0.1428571
 4: 2015-05-05 0.7142857 0.4285714 0.1428571
 5: 2015-05-06 0.7142857 0.4285714 0.1428571
 6: 2015-05-07 0.7142857 0.4285714 0.1428571
 7: 2015-05-08 0.7142857 0.4285714 0.1428571
 8: 2015-05-09 0.8571429 0.5714286 0.2857143
 9: 2015-05-10 0.8571429 0.5714286 0.2857143
10: 2015-05-11 0.8571429 0.5714286 0.2857143
11: 2015-05-12 0.8571429 0.5714286 0.2857143
12: 2015-05-13 0.8571429 0.5714286 0.2857143
13: 2015-05-14 0.8571429 0.5714286 0.2857143
14: 2015-05-15 0.8571429 0.5714286 0.2857143

说明:

使用setDT(df)将数据帧转换为数据表(这是一个增强的数据帧)。使用by = date按日期分组。假设原始数据框中的每个日期都是一周的开始日期,您可以使用as.Date(date:(date+6), origin="1970-01-01")创建完整的一周。

使用过的数据:

df <- data.frame(date = c("2015-05-02", "2015-05-09"),
                 cost_a = c(5, 6),
                 cost_b = c(3, 4),
                 cost_c = c(1, 2))
df$date <- as.Date(df$date)