根据一列的值组合数据

时间:2015-08-31 11:39:45

标签: r

我在R

中有一个数据框
     year group  sales
1   2000     1    20
2   2001     1    25
3   2002     1    23
4   2003     1    30
5   2001     2    50
6   2002     2    55

我想按组对数据进行分组或创建某种对象。我想为每个组创建一个数组,用于存储年份和销售额。我将尝试将其保存为具有以下结构的json文件:

[{"group": 1, "sales":[[2000,20],[2001, 25], [2002,23], [2003, 30]]},
{"group": 2, "sales":[[2001, 50], [2002,55]]}] 

是否可以自动完成?

非常感谢

2 个答案:

答案 0 :(得分:2)

我们可以使用data.tablepaste年份'和'销售'按'组分组的列。我们转换了' data.frame'到' data.table' (setDT(df1))。通过' group'分组,我们使用sprintf来粘贴'年'' sales'连同括号([]),然后将输出折叠为包含toString的单个字符串(它是paste(..., collapse=', ')的包装),paste [] ,并使用toJSON

library(jsonlite)
library(data.table)
toJSON(setDT(df1)[, list(sales= paste0('[',toString(sprintf('[%d,%d]',
                  year, sales)),']')), by = group])
#[{"group":1,"sales":"[[2000,20], [2001,25], [2002,23], [2003,30]]"},
#{"group":2,"sales":"[[2001,50], [2002,55]]"}] 

可以使用paste按组base R完成。我们split数据集由'组'组成。用于创建list的列。使用listlapply,'年''销售'循环遍历paste。如上所述的列。使用' group'的第一个元素创建data.frame以及来自paste步骤的字符串,rbind list元素来创建单个data.frame,然后使用toJSON

toJSON(
     do.call(rbind,
         lapply(
            split(df1, df1$group),
                function(x) data.frame(group=x$group[1L], 
                           sales=paste0('[',
                            toString(sprintf('[%d,%d]', x$year, x$sales)),
              ']')))))

数据

df1 <- structure(list(year = c(2000L, 2001L, 2002L, 2003L, 2001L, 2002L
 ), group = c(1L, 1L, 1L, 1L, 2L, 2L), sales = c(20L, 25L, 23L, 
30L, 50L, 55L)), .Names = c("year", "group", "sales"), 
class = "data.frame", row.names = c(NA, -6L))

答案 1 :(得分:0)

由于另一个答案使用data.table,我认为在dplyr尝试执行此操作会很有趣。这不是最佳方式,但说明do,我不相信已经记录得足够好。我还展示了更合适的summarise解决方案。

df <-read.table(textConnection('
year   group sales  expenses
2000     1    20     19
2001     1    25     19
2002     1    23     20
2003     1    30     15
2001     2    50     27
2002     2    55     30
'),header=TRUE)   


library(dplyr)
library(jsonlite)

df %>%
  group_by( group ) %>%
  do(
     sales = group_by(.,year) %>% select(sales) %>% apply(MARGIN=2,identity),
     expenses = group_by(.,year) %>% select(expenses) %>% apply(MARGIN=2,identity)
  )

df %>%
  group_by( group ) %>%
  summarise(
    sales = list(apply( data.frame(year,sales), MARGIN=2, identity ))
    ,expenses = list(apply( data.frame(year,sales), MARGIN=2, identity ))
  ) %>% jsonlite::toJSON()