簡體   English   中英

R:如何將 dataframe 中的一行拆分為多行,以單元格中的值為條件?

[英]R: How to split a row in a dataframe into a number of rows, conditional on a value in a cell?

我有一個如下所示的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

這給出了一個看起來像這樣的df

     id   age_from  age_to     y      years
1     a       0       2       100       2
2     a       2       3       150       1
3     a       3       7       100       4
4     a       7       10      250       3
5     b       0       1       300       1
6     b       1       2       200       1
7     b       2       6       100       4
8     b       6       10      150       4

我不想每行有不相等的年數,而是有 20 行,每個id 10 行,每行占一年。 這還涉及對年列中列出的years數的y列進行平均。

我相信這可能必須使用循環1:n來完成,其中n等於years列中的值。 雖然我不確定如何開始。

您可以使用rep按給定數重復行。

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

當您的意思是將 y 列平均跨年數除以年數時:

x$y <- x$y / x$years

如果age_from應該 go 從09age_to110對於每個 id:

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

這是tidyrdplyr的解決方案。

首先,我們通過僅保留現有的idcomplete從 0 到 9 的age_from

您將在age_toyyears上有幾個NA 因此,我們通過向下拖動每個值來填充它們,以完成緊隨其后的NA值。

現在您可以將y除以years (我假設您的意思是設置平均值以使總和保持一致)。

此時,您只需要相應地重新計算age_to

最后記得ungroup

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()
# 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

一個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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM