简体   繁体   中英

Repeat rows in a dataframe based on a condition in R

I have a dataframe that looks like this:

STAND Plot1 X    DBH   Spec   HT              NOTES
1   TEN YEAR VAR RET     1 s   1.25    ASH   NA                   
2   TEN YEAR VAR RET     1 s   1.25    ASH   NA                   
3   TEN YEAR VAR RET     1 s   1.25    ASH   NA                   
4   TEN YEAR VAR RET     1 s   1.25    ASH   NA                   
5   TEN YEAR VAR RET     1 s   1.25    ASH   NA                   

I need to repeat a block of rows a number of times (different number for different blocks). So I have a stand (STAND) and 5*2 plots in each stand. 5 plots are small (X = "s"), and another 5 are large (X = "L"). I need to duplicate rows for each large plot 20 times, and each small plot 500 times. So the condition for the block to be repeated would be something like this:

STAND == "TEN YEAR VAR RET", Plot1 == "1", X == "s"  * 500
STAND == "TEN YEAR VAR RET", Plot1 == "2", X == "s"  * 500 etc

And for the large plot if would be something like:

STAND == "TEN YEAR VAR RET", Plot1 == "1", X == "L"  * 20
STAND == "TEN YEAR VAR RET", Plot1 == "2", X == "L"  * 20 etc

Any advice is appreciated!

We could create some numeric index of the rows

#row index with 's' value for X
i1 <- with(df1, which(STAND == "TEN YEAR VAR RET" & Plot1 %in%  c("1", "2")& X == "s"))
#row index for 'L' value for X
i2 <- with(df1, which(STAND == "TEN YEAR VAR RET" & Plot1 %in%  c("1", "2")& X == "L"))
#row index for those that doesn't belong to the above 2
i3 <- which(!seq_len(nrow(df1)) %in% c(i1, i2))

and then replicate the rows to expand the dataset

n1 <- 500
n2 <- 20
df2 <- df1[sort(c(rep(i1, each =  n1), i3, rep(i2, each = n2))),]

data

df <- read.table(text="
             STAND Plot1 X    DBH   Spec   HT
'TEN YEAR VAR RET'     1 s   1.25    ASH   NA                   
'TEN YEAR VAR RET'     2 s   1.25    ASH   NA                   
'TEN YEAR VAR RET'     2 L   1.25    ASH   NA                   
'TEN YEAR VAR RET'     1 s   1.25    ASH   NA                   
'TEN YEAR VAR RET'     3 L   1.25    ASH   NA                   
'AAAAAAAAAAAAAAAA'     2 s   1.25    ASH   NA                   
'AAAAAAAAAAAAAAAA'     3 s   1.25    ASH   NA                   
'TEN YEAR VAR RET'     2 s   1.25    ASH   NA",stringsAsFactors=F,header=T)

Solution

library(dplyr)
library(tidyr)
library(magrittr)

df %>%
  mutate(times=case_when(
    Plot1 == 1 ~ 2, # <- change values (and possibly condition) here
    Plot1 == 2 ~ 3, # <- and here
    TRUE ~ 1)) %>%
  group_by(times) %>%
  nest %$%
  map2_dfr(data,times,~.x[rep(seq(nrow(.x)),each=.y),])

# A tibble: 18 x 6
#               STAND Plot1     X   DBH  Spec    HT
#               <chr> <int> <chr> <dbl> <chr> <lgl>
#  1 TEN YEAR VAR RET     1     s  1.25   ASH    NA
#  2 TEN YEAR VAR RET     1     s  1.25   ASH    NA
#  3 TEN YEAR VAR RET     1     s  1.25   ASH    NA
#  4 TEN YEAR VAR RET     1     s  1.25   ASH    NA
#  5 TEN YEAR VAR RET     2     s  1.25   ASH    NA
#  6 TEN YEAR VAR RET     2     s  1.25   ASH    NA
#  7 TEN YEAR VAR RET     2     s  1.25   ASH    NA
#  8 TEN YEAR VAR RET     2     L  1.25   ASH    NA
#  9 TEN YEAR VAR RET     2     L  1.25   ASH    NA
# 10 TEN YEAR VAR RET     2     L  1.25   ASH    NA
# 11 AAAAAAAAAAAAAAAA     2     s  1.25   ASH    NA
# 12 AAAAAAAAAAAAAAAA     2     s  1.25   ASH    NA
# 13 AAAAAAAAAAAAAAAA     2     s  1.25   ASH    NA
# 14 TEN YEAR VAR RET     2     s  1.25   ASH    NA
# 15 TEN YEAR VAR RET     2     s  1.25   ASH    NA
# 16 TEN YEAR VAR RET     2     s  1.25   ASH    NA
# 17 TEN YEAR VAR RET     3     L  1.25   ASH    NA
# 18 AAAAAAAAAAAAAAAA     3     s  1.25   ASH    NA

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM