R 重复每行数据。按列中指定的次数设置帧

R 重复每行数据。按列中指定的次数设置帧,r,dataframe,replicate,R,Dataframe,Replicate,为此: df var1 var2 freq 1 a d 1 2 b e 2 3 c f 3 这里有一个解决方案: df.expanded var1 var2 1 a d 2 b e 3 b e 4 c f 5 c f 6 c f @neilfws的解决方案适用于data.frames,但不适用于data.tables,因为它们缺少row.names属性。这种方

为此:

df
  var1 var2 freq
1    a    d    1
2    b    e    2
3    c    f    3
这里有一个解决方案:

df.expanded
  var1 var2
1    a    d
2    b    e
3    b    e
4    c    f
5    c    f
6    c    f

@neilfws的解决方案适用于data.frames,但不适用于data.tables,因为它们缺少row.names属性。这种方法适用于以下两种情况:

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f
使用splitstackshape包中的expandRows:

简单语法,非常快速,适用于data.frame或data.table

结果:

df.expanded <- df[rep(row.names(df), df$freq), 1:2]

如果您必须在非常大的data.frames上执行此操作,我建议将其转换为data.table并使用以下命令,这将运行得更快:

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f
查看此解决方案的速度有多快:

library(data.table)
dt <- data.table(df)
dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")]
dt.expanded[ ,freq := NULL]
dt.expanded

旧问题,新动词在tidyverse中:

df <- data.frame(var1=1:2e3, var2=1:2e3, freq=1:2e3)
system.time(df.exp <- df[rep(row.names(df), df$freq), 1:2])
##    user  system elapsed 
##    4.57    0.00    4.56
dt <- data.table(df)
system.time(dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")])
##    user  system elapsed 
##    0.05    0.01    0.06

另一种可能是使用tidyr::expand:

图书馆弹琴 图书馆三年 df%>%group\U by\U atvars-freq%>%expandtemp=1:freq%>%select temp 由v0.2.1创建于2019-05-21,是另一个dplyr替代方案,带有切片,我们在其中重复每一行号的频率

seq_lenn零件可替换为以下任一零件

library(dplyr)

df %>%  
  slice(rep(seq_len(n()), freq)) %>% 
  select(-freq)

#  var1 var2
#1    a    d
#2    b    e
#3    b    e
#4    c    f
#5    c    f
#6    c    f

我知道情况并非如此,但如果您需要保留原始的freq列,您可以与rep一起使用另一种tidyverse方法:

图书馆咕噜声 df% 地图方向,代表,$freq >一个tibble:6x3 >var1 var2频率 > >1 a d 1 >2 b e 2 >3 b e 2 >4 c f 3 >5立方英尺3英寸 >6CF3
实际上是由v0.3.0于2019年12月21日创建的。使用向量和索引的方法。我们还可以实现同样的结果,并且更容易理解:

df %>% slice(rep(1:nrow(df), freq)) %>% select(-freq)
#Or
df %>% slice(rep(row_number(), freq)) %>% select(-freq)
#Or
df %>% slice(rep(seq_len(nrow(.)), freq)) %>% select(-freq)

伟大的我总是忘了你可以用方括号。我一直在想索引只是为了子集或重新排序。我有另一个解决方案,它远没有那么优雅,毫无疑问也没有那么有效。无论如何,我可能会发布文章,以便其他人能够进行比较。对于大数据.frame,更有效的方法是用seq.int1、nrowdf或seq_lennrowdf替换row.namedf。这对于大数据帧来说非常有效—150万行,5列,运行非常快。谢谢1:2硬编码本例的解决方案,1:ncoldf将适用于任意数据帧。我得到一个错误:rep1中的错误,freq:invalid'times'参数。考虑到这个问题已经有了data.table答案,您可能需要描述您的方法与当前data.table答案有何不同,或者何时优于当前data.table答案。或者,如果没有重大区别,您可以将其添加为现有答案的注释。@SamFirke:谢谢您的评论。奇怪的是,我又试了一次,却没有发现这样的错误。您是否使用OP问题的原始DF?我的答案更好,因为另一个答案是使用data.frame语法滥用data.table包,请参阅data.table的常见问题解答:通常按数字而不是名称引用列是不好的做法。感谢您的解释。您的代码在OP发布的示例df上对我有效,但是当我尝试在更大的data.frame上对其进行基准测试时,我得到了那个错误。我使用的data.frame是:set.seed1 dfbig@SamFirke:这确实很奇怪,它在那里也应该工作,我不知道为什么它不工作。你想从中引出一个问题还是我来?好主意。你能?我不知道data.table语法,所以我不应该是判断答案的人。另一个选项:df[repseq.N,freq][,freq:=NULL]另一个选项df[rep1:.N,freq][,freq:=NULL]或者在uncount中使用。remove=FALSE
library(data.table)
dt <- data.table(df)
dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")]
dt.expanded[ ,freq := NULL]
dt.expanded
df <- data.frame(var1=1:2e3, var2=1:2e3, freq=1:2e3)
system.time(df.exp <- df[rep(row.names(df), df$freq), 1:2])
##    user  system elapsed 
##    4.57    0.00    4.56
dt <- data.table(df)
system.time(dt.expanded <- dt[ ,list(freq=rep(1,freq)),by=c("var1","var2")])
##    user  system elapsed 
##    0.05    0.01    0.06
library(tidyr) # version >= 0.8.0
df <- data.frame(var1=c('a', 'b', 'c'), var2=c('d', 'e', 'f'), freq=1:3)
df %>% 
  uncount(freq)

    var1 var2
1      a    d
2      b    e
2.1    b    e
3      c    f
3.1    c    f
3.2    c    f
#> # A tibble: 6 x 2
#> # Groups:   var1, var2 [3]
#>   var1  var2 
#>   <fct> <fct>
#> 1 a     d    
#> 2 b     e    
#> 3 b     e    
#> 4 c     f    
#> 5 c     f    
#> 6 c     f
#>    var1 var2
#> 1:    a    d
#> 2:    b    e
#> 3:    b    e
#> 4:    c    f
#> 5:    c    f
#> 6:    c    f
library(dplyr)

df %>%  
  slice(rep(seq_len(n()), freq)) %>% 
  select(-freq)

#  var1 var2
#1    a    d
#2    b    e
#3    b    e
#4    c    f
#5    c    f
#6    c    f
df %>% slice(rep(1:nrow(df), freq)) %>% select(-freq)
#Or
df %>% slice(rep(row_number(), freq)) %>% select(-freq)
#Or
df %>% slice(rep(seq_len(nrow(.)), freq)) %>% select(-freq)
rawdata <- data.frame('time' = 1:3, 
           'x1' = 4:6,
           'x2' = 7:9,
           'x3' = 10:12)

rawdata[rep(1, time=2), ] %>% remove_rownames()
#  time x1 x2 x3
# 1    1  4  7 10
# 2    1  4  7 10