2016-07-28 80 views
0

我基本上想做的是ddply(df, columns.to.preserve, numcolwise(FUNCTION)的相反。数据帧的逐行扩展

假设我有

d <- data.frame(
    count=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或其他包,做这种手术?

编辑:这与De-aggregate/reverse-summarise/expand a dataset in R问题有所不同,因为我想进一步实际应用不同的函数到我希望展开的表内的列。这篇文章中还有更多有用的答案。

+4

一些地方开始扩大data.frame [这里](HTTP ://stackoverflow.com/questions/38208529/de-aggregate-reverse-summarise-expand-a-dataset-in-r)。一旦完成,只需用'count'将'summed.value'和'count'分开。 – aosmith

回答

2

使用dplyrtidyr,你可以做一个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 ,您可以在其中指定行号作为组变量,并且数据表将自动扩展它:

library(data.table) 
setDT(d) 
d[, .(summed.value = rep(summed.value/count, count), averaged.value, count = 1), .(1:nrow(d))] 
[, nrow := NULL][] 

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

有一个功能untable重塑获取表的反转。然后将需要除以count的变量除以mutate_at(或mutate_each)。 mutate_at被引入dplyr_0.5.0

首先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_at分割summed.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 
+0

'mutate_at'从哪里来?它似乎不在'plyr'或'dplyr'中。另外,你碰巧知道为什么'untable'不在'reshape2'中? – Warner

+0

mutate_at'在当前版本的dplyr中。我不知道为什么'untable'没有带入reshape2。 – aosmith

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 
1

这里是一个既简单又充分vecotrized基础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