从数据框聚合多个列

时间:2017-08-30 05:56:08

标签: r

我有一个数据框,其中包含一些数据,这些数据在行的某些元素中以逗号连接。看起来像:

df <- data.frame(
c(2012,2012,2012,2013,2013,2013,2014,2014,2014)
,c("a,b,c","d,e,f","a,c,d,c","a,a,a","b","c,a,d","g","a,b,e","g,h,i")
)
 names(df) <- c("year", "type")

我想以dcast接近它的形式得到它,其中年,a,b,c等是列,数据帧中的频率在单元格中得到的数据帧。我首先尝试在colsplitdf然后使用dcast,但这似乎只有在我想在其中一个级别而不是所有级别上聚合时才有效。

 df2 <- data.frame( df$year,  colsplit(df$type, ',' , c('v1','v2','v3','v4','v5')) )
 df3 <- dcast(df2, df.year ~ v1)

此结果仅为我提供colsplit的第一级,而不是所有级别。我接近解决方案还是应该完全使用不同的方法?

4 个答案:

答案 0 :(得分:3)

以下是base R的单行选项,将“类型”列与strsplit分开,然后将list输出的名称设置为“年”,{{1}将它添加到单个data.frame并使用stack

获取频率计数
table

答案 1 :(得分:1)

您接近解决方案。你只需要再做一步。在@RestController public class TestController { @RequestMapping(value = "/getString", produces = MediaType.APPLICATION_JSON_VALUE) public Map getString() { return Collections.singletonMap("response", "Hello World"); } } 之前,您需要melt一列中的所有值dcast。参见示例。

require(reshape2)

df <- data.frame(c(2012,2012,2012,2013,2013,2013,2014,2014,2014),
                 c("a,b,c","d,e,f","a,c,d,c","a,a,a","b","c,a,d","g","a,b,e","g,h,i"))
names(df) <- c("year", "type")
df

df2 <- data.frame(df$year, colsplit(df$type, ',', c('v1','v2','v3','v4','v5')))
df2

df3 <- melt(df2, id.vars = "df.year", na.rm = T)
df3

df4 <- dcast(df3[df3$value != "", ], df.year ~ value, fun.aggregate = length)
df4

答案 2 :(得分:1)

这是一个data.table方法:

library(data.table)
setDT(df)
dcast(df[, .(unlist(strsplit(as.character(type), ",", fixed=TRUE))), by = year], 
 year ~ V1, value.var = "V1", fun.aggregate = length)
#   year a b c d e f g h i
#1: 2012 2 1 3 2 1 1 0 0 0
#2: 2013 4 1 1 1 0 0 0 0 0
#3: 2014 1 1 0 0 1 0 2 1 1

我们首先将逗号和每年组的类型列拆分为长格式,然后将dcast拆分为宽length作为聚合函数。

答案 3 :(得分:0)

也许,这样的事情可行吗?

# extract unique values and years
    vals <- unique(do.call(c, strsplit(x = as.vector(df$type), "[[:punct:]]")))
    years <- unique(df$year)

# count
    df4 <- data.frame(sapply(vals, (function(vl) {sapply(years, (function(ye){ 
      sum(do.call(c, strsplit(as.vector(df$type[df$year == ye]) , "[[:punct:]]")) == vl)
    }))})))
    df4 <- cbind(years, df4)
    df4
#result
  years a b c d e f g h i
1  2012 2 1 3 2 1 1 0 0 0
2  2013 4 1 1 1 0 0 0 0 0
3  2014 1 1 0 0 1 0 2 1 1