R:如何根据单元格中的值将数据帧中的一行拆分为多行?

R:如何根据单元格中的值将数据帧中的一行拆分为多行?,r,dataframe,R,Dataframe,我有一个data.frame,如下所示: id <- c("a","a","a","a","b","b","b","b") age_from <- c(0,2,3,7,0,1,2,6) age_to <- c(2,3,7,10,1,2,6,10) y <- c(100,150,100,250,300,200,100

我有一个
data.frame
,如下所示:

id <- c("a","a","a","a","b","b","b","b")
age_from <- c(0,2,3,7,0,1,2,6)
age_to <- c(2,3,7,10,1,2,6,10)
y <- c(100,150,100,250,300,200,100,150)
df <- data.frame(id,age_from,age_to,y)
df$years <- df$age_to - df$age_from
我不希望每行的年数不相等,而是希望有20行,每个
id
对应10行,每行占一年。这还包括对
y
列中列出的年数取平均值


我认为这可能必须使用循环
1:n
,其中
n
等于
years
列中的值。虽然我不知道如何从这个开始。

这里有一个使用
tidyr
dplyr
的解决方案

首先,我们只保留现有的
id
s,根据您的需要,完成
年龄从0到9的过程

您将在
u至
y
上有几个
NA
s。因此,我们通过向下拖动每个值来填充它们,以便完成紧随其后的
NA

现在您可以将
y
除以
years
(我假设您的意思是设置平均值,使总和保持一致)

此时,您只需相应地重新计算年龄

请记住在末尾取消分组

library(tidyr)
library(dplyr)

df %>%
  complete(id, age_from = 0:9) %>% 
    group_by(id) %>%
    fill(y, years, age_to) %>% 
    mutate(y = y/years) %>% 
    mutate(age_to = age_from + 1) %>% 
    ungroup()
#一个tible:20 x 5
id年龄从年龄到y岁
1A 01 50 2
2 a 1 2 50 2
3 a 2 3 150 1
4 a 3 4 25 4
5 a 4 5 25 4
6 a 5 6 25 4
7 a 6 7 25 4
8 a 7 8 83.3 3
9 a 8 9 83.3 3
10 a 9 10 83.3 3
11B013001
12B122001
13 b 2 3 25 4
14 b 3 4 25 4
15 b 4 5 25 4
16 b 5 6 25 4
17 b 6 7 37.5 4
18 b 7 8 37.5 4
19 b 8 9 37.5 4
20 b 9 10 37.5 4

您可以使用
rep
按给定年数重复行


一个
tidyverse
解决方案

library(tidyverse)

df %>%
  mutate(age_to = age_from + 1) %>% 
  group_by(id) %>% 
  complete(nesting(age_from = 0:9, age_to = 1:10)) %>%
  fill(y, years) %>%
  mutate(y = y / years)

# A tibble: 20 x 5
# Groups:   id [2]
   id    age_from age_to     y years
   <chr>    <dbl>  <dbl> <dbl> <dbl>
 1 a            0      1  50       2
 2 a            1      2  50       2
 3 a            2      3 150       1
 4 a            3      4  25       4
 5 a            4      5  25       4
 6 a            5      6  25       4
 7 a            6      7  25       4
 8 a            7      8  83.3     3
 9 a            8      9  83.3     3
10 a            9     10  83.3     3
11 b            0      1 300       1
12 b            1      2 200       1
13 b            2      3  25       4
14 b            3      4  25       4
15 b            4      5  25       4
16 b            5      6  25       4
17 b            6      7  37.5     4
18 b            7      8  37.5     4
19 b            8      9  37.5     4
20 b            9     10  37.5     4
库(tidyverse)
df%>%
突变(年龄从+1到=年龄从+1)%>%
分组依据(id)%>%
完成(嵌套(年龄从=0:9,年龄从=1:10))%>%
填充(y,年)%>%
突变(y=y/年)
#一个tibble:20x5
#组别:id[2]
id年龄从年龄到y岁
1A 01 50 2
2 a 1 2 50 2
3 a 2 3 150 1
4 a 3 4 25 4
5 a 4 5 25 4
6 a 5 6 25 4
7 a 6 7 25 4
8 a 7 8 83.3 3
9 a 8 9 83.3 3
10 a 9 10 83.3 3
11B013001
12B122001
13 b 2 3 25 4
14 b 3 4 25 4
15 b 4 5 25 4
16 b 5 6 25 4
17 b 6 7 37.5 4
18 b 7 8 37.5 4
19 b 8 9 37.5 4
20 b 9 10 37.5 4

您希望如何插值这些值?
a
的y值
100
是0、2处的值,还是在0和2之间的平均点(即:1)处的值?0和10的值是多少?请手动进行插值并显示所需的输出。否则,就不可能创建您想要的循环。非常酷的解决方案。不过,如果我理解正确,我相信每个
id
age\u从
应该从0到9,从
age\u到
从1到10。需要确认吗@stackedit1007@Edo谢谢我为这个案例添加了一些行。
# A tibble: 20 x 5
   id    age_from age_to     y years
   <chr>    <dbl>  <dbl> <dbl> <dbl>
 1 a            0      1  50       2
 2 a            1      2  50       2
 3 a            2      3 150       1
 4 a            3      4  25       4
 5 a            4      5  25       4
 6 a            5      6  25       4
 7 a            6      7  25       4
 8 a            7      8  83.3     3
 9 a            8      9  83.3     3
10 a            9     10  83.3     3
11 b            0      1 300       1
12 b            1      2 200       1
13 b            2      3  25       4
14 b            3      4  25       4
15 b            4      5  25       4
16 b            5      6  25       4
17 b            6      7  37.5     4
18 b            7      8  37.5     4
19 b            8      9  37.5     4
20 b            9     10  37.5     4
x <- df[rep(seq_len(nrow(df)), df$years),]
x
#    id age_from age_to         y years
#1    a        0      2  50.00000     2
#1.1  a        0      2  50.00000     2
#2    a        2      3 150.00000     1
#3    a        3      7  25.00000     4
#3.1  a        3      7  25.00000     4
#3.2  a        3      7  25.00000     4
#3.3  a        3      7  25.00000     4
#4    a        7     10  83.33333     3
#4.1  a        7     10  83.33333     3
#4.2  a        7     10  83.33333     3
#5    b        0      1 300.00000     1
#6    b        1      2 200.00000     1
#7    b        2      6  25.00000     4
#7.1  b        2      6  25.00000     4
#7.2  b        2      6  25.00000     4
#7.3  b        2      6  25.00000     4
#8    b        6     10  37.50000     4
#8.1  b        6     10  37.50000     4
#8.2  b        6     10  37.50000     4
#8.3  b        6     10  37.50000     4
x$y <- x$y / x$years
x$age_from <- x$age_from + ave(x$age_from, x$id, x$age_from, FUN=seq_along) - 1
#x$age_from <- ave(x$age_from, x$id, FUN=seq_along) - 1 #Alternative
x$age_to <- x$age_from + 1
library(tidyverse)

df %>%
  mutate(age_to = age_from + 1) %>% 
  group_by(id) %>% 
  complete(nesting(age_from = 0:9, age_to = 1:10)) %>%
  fill(y, years) %>%
  mutate(y = y / years)

# A tibble: 20 x 5
# Groups:   id [2]
   id    age_from age_to     y years
   <chr>    <dbl>  <dbl> <dbl> <dbl>
 1 a            0      1  50       2
 2 a            1      2  50       2
 3 a            2      3 150       1
 4 a            3      4  25       4
 5 a            4      5  25       4
 6 a            5      6  25       4
 7 a            6      7  25       4
 8 a            7      8  83.3     3
 9 a            8      9  83.3     3
10 a            9     10  83.3     3
11 b            0      1 300       1
12 b            1      2 200       1
13 b            2      3  25       4
14 b            3      4  25       4
15 b            4      5  25       4
16 b            5      6  25       4
17 b            6      7  37.5     4
18 b            7      8  37.5     4
19 b            8      9  37.5     4
20 b            9     10  37.5     4