逐行扩展data.frame

时间:2016-07-28 14:46:19

标签: r dplyr

我基本上想要与ddply相反(df,columns.to.preserve,numcolwise(FUNCTION)。 假设我有 d< - data.frame(   计数= C(2,1,3),   summed.value = C(50,20,30),   averaged.value = C(35,80,20) )       count summed.value averaged.value 1 2 50 35 2 1 20 80 3 3 30 20 我想基于count列对这个data.frame进行行扩展,同时指定我想要应用于其他列的操作类型。 以下是我正在寻找的结果: > D2   count summed.value averaged.value 1 1 25 35 2 1 25 35 3 1 20 80 4 1 10 20 5 1 10 20 6 1 10 20 在dplyr或其他包中执行此类操作的内置函数是什么? 编辑:这与R问题中的去聚合/反向汇总/扩展数据集不同,因为我想更进一步,实际上将不同的函数应用于我希望扩展的表中的列。这篇文章还有更多有用和答案。

4 个答案:

答案 0 :(得分:2)

使用Typedplyr,您可以为tidyr进行rowwise转换,为每个单元格生成一个列表,然后summed.value列应该给你你需要的东西:

unnest

另一种方法是使用library(dplyr); library(tidyr) d %>% rowwise() %>% summarise(summed.value = list(rep(summed.value/count, count)), averaged.value = averaged.value, count = 1) %>% unnest() # Source: local data frame [6 x 3] # averaged.value count summed.value # <dbl> <dbl> <dbl> # 1 35 1 25 # 2 35 1 25 # 3 80 1 20 # 4 20 1 10 # 5 20 1 10 # 6 20 1 10 ,您可以在其中将行号指定为组变量,数据表将自动展开它:

data.table

答案 1 :(得分:2)

重塑中有一个函数untable,用于获取表的反转。然后将需要除count的变量除以mutate_at(或mutate_each)。 dplyr_0.5.0 中引入了mutate_at

首先是untable

library(reshape)
untable(d, num = d$count)

    count summed.value averaged.value
1       2           50             35
1.1     2           50             35
2       1           20             80
3       3           30             20
3.1     3           30             20
3.2     3           30             20

然后mutate_atsummed.valuecount划分为count

library(dplyr)

untable(d, num = d$count) %>%
    mutate_at(vars(summed.value, count), funs(./count))

  count summed.value averaged.value
1     1           25             35
2     1           25             35
3     1           20             80
4     1           10             20
5     1           10             20
6     1           10             20

答案 2 :(得分:1)

这是一个既简单又完全归正的基础R方法

transform(d[rep(1:nrow(d), d$count), ], 
          count = 1, 
          summed.value = summed.value/count)
#     count summed.value averaged.value
# 1       1           25             35
# 1.1     1           25             35
# 2       1           20             80
# 3       1           10             20
# 3.1     1           10             20
# 3.2     1           10             20

或类似地,使用data.table

library(data.table)
res <- setDT(d)[rep(1:.N, count)][, `:=`(count = 1, summed.value = summed.value / count)]
res
#    count summed.value averaged.value
# 1:     1           25             35
# 2:     1           25             35
# 3:     1           20             80
# 4:     1           10             20
# 5:     1           10             20
# 6:     1           10             20 

答案 3 :(得分:0)

基础R解决方案:它尝试按count列的值复制每一行,然后将countsummed.value列除以count

mytext <- 'count,summed.value,averaged.value
2,50,35
1,20,80
3,30,20'

mydf <-  read.table(text=mytext,header=T,sep = ",")

mydf <- do.call(rbind,apply(mydf, 1, function(x) {
  tempdf <- t(replicate(x[1],x,simplify = T))
  tempdf[,1] <- tempdf[,1]/x[1]
  tempdf[,2] <- tempdf[,2]/x[1]
  return(data.frame(tempdf))
}))

count summed.value averaged.value
     1           25             35
     1           25             35
     1           20             80
     1           10             20
     1           10             20
     1           10             20