R 使列表的每个元素都是自己的行(基于列值的列表)
我有一个data.frame对象:R 使列表的每个元素都是自己的行(基于列值的列表),r,dataframe,dplyr,tidyr,R,Dataframe,Dplyr,Tidyr,我有一个data.frame对象: subject <- c("Nantes", "Nantes", "Nantes", "Brest", "Brest", "Rennes") page <- c(1, 2, 3, 1, 2, 1) rows <- c(2, 3, 4, 6, 2, 3) df <- data.frame (subject,page, rows) 南特主题:第1页第2页第3页。 每一页有不同的行数。对于南特,第1页有2行 我想要的是:根据1:nrow序列
subject <- c("Nantes", "Nantes", "Nantes", "Brest", "Brest", "Rennes")
page <- c(1, 2, 3, 1, 2, 1)
rows <- c(2, 3, 4, 6, 2, 3)
df <- data.frame (subject,page, rows)
南特主题:第1页第2页第3页。每一页有不同的行数。对于南特,第1页有2行 我想要的是:根据1:nrow序列复制每一行 例如:我需要将Nantes第1页打印两次
subject page rows
Nantes 1 1
Nantes 1 2
Nantes 2 1
Nantes 2 2
Nantes 2 3
Nantes 3 1
Nantes 3 2
Nantes 3 3
Nantes 3 3
Nantes 3 4
Brest 1 1
Brest 1 2
Brest 1 3
Brest 1 4
Brest 1 5
Brest 1 6
Rennes 1 1
Rennes 1 2
Rennes 1 3
基于,我可以使用unnest函数,但无法解决我的问题。我们可以使用
purrr
包中的map
创建行中的整数序列列表。在此之后,unest
数据帧df2
是最终输出
library(tidyverse)
df2 <- df %>%
mutate(rows = map(rows, seq)) %>%
unnest()
库(tidyverse)
df2%
突变(行=映射(行,序列))%>%
unnest()
在base R中,您可以
dfNew <- data.frame(subject=rep(df$subject, df$rows),
page=rep(df$page, df$rows),
rows=sequence(df$rows))
使用和可能会更干净一些:
dfNew <- with(df, data.frame(subject=rep(subject, rows),
page=rep(page, rows),
rows=sequence(rows)))
dfNew如果按其他列分组,可以使用tidyr::complete
和seq
来填写缺少的观察结果:
库(tidyverse)
df%
完成(行=序号(行))
df_扩展
#>#tibble:20 x 3
#>#分组:主题,第[6]页
#>主题页行
#>
#>1布雷斯特11
#>2布雷斯特12
#>3布雷斯特1 3
#>4布雷斯特14
#>5布雷斯特15
#>6布雷斯特16
#>7布雷斯特2 1
#>8布雷斯特2
#>9南特1
#>10南特12
#>11南特2 1
#>12南特2
#>13南特2 3
#>14南特3 1
#>15南特3 2
#>16南特3 3
#>17南特3 4
#>18雷恩1
#>19雷恩1 2
#>20雷恩1 3
这种方法的优点是,如果一个主题
/页面
组合已经部分展开,它就不会被复制。只要它不是一个海量数据框架,应用
也可以工作
do.call(rbind, apply(X = df, MARGIN = 1, function(x)
data.frame(subject = x[1],
page = as.numeric(x[2]),
rows = sequence(x[3]),
row.names = NULL)))
映射(行,序列)
会有点simpler@alistaire谢谢分享你的想法。我会根据你的建议更新答案。比do.call(rbind,lappy(split(df,paste(df$subject,df$page)),function(a)data.frame(subject=a$subject,page=a$page,rows=sequence(a$rows)))好得多。
@d.b是的,我喜欢lappy
/split
方法,但在某些问题上,它可能相当沉重;您已将页面
转换为数字因子。
dfNew <- with(df, data.frame(subject=rep(subject, rows),
page=rep(page, rows),
rows=sequence(rows)))
do.call(rbind, apply(X = df, MARGIN = 1, function(x)
data.frame(subject = x[1],
page = as.numeric(x[2]),
rows = sequence(x[3]),
row.names = NULL)))