Home > OS >  Filling new column using rep() based specific value (years) in other column in R
Filling new column using rep() based specific value (years) in other column in R

Time:10-08

I have seen this question before: R adding a new column in a data frame by recursivly filling 1:3 value based on another column

my question is probably the same, but my case is a little different

Let's say I want to fill a new column based on the below number range:

   Group Range
1      A  2-4
2      B  6-8
3      C  10-12

the data frame:

df <- data.frame(Group = rep(c("A", "B", "C"),  times = c(2, 4, 6))
> df
   Group
1      A
2      A
3      B
4      B
5      B
6      B
7      C
8      C
9      C
10     C
11     C
12     C

My case is I want to add a new column Type by recursively filling based on the range column.

The resulting DF is like this:

> df2
   Group   Type
1      A      2
2      A      3
3      B      6
4      B      7
5      B      8
6      B      6
7      C     10
8      C     11
9      C     12
10     C     10
11     C     11
12     C     12

I tried to use mutate like below:

df <- df %>% group_by(Group) %>% 
mutate(Type = if_else(Group == "A",rep_len(2:4, length.out = 2), 0), .after = Group)
df

but it still doesn't work

what is the correct script for this case, especially if there is additional data in the Group column?

Thank you for the help

CodePudding user response:

Using mapply and strsplit it can be done

df1: 
   Group Range
1      A  2-4
2      B  6-8
3      C  10-12



df2$Type <- unlist(mapply(\(x,y){
  a <- as.numeric(y)
  
  rep(seq(a[1], a[2]), length = x)
  
}, c(2,4,6), strsplit(df1$Range, "-")))

   Group Type
1      A    2
2      A    3
3      B    6
4      B    7
5      B    8
6      B    6
7      C   10
8      C   11
9      C   12
10     C   10
11     C   11
12     C   12

CodePudding user response:

How do you like this way.

For another dataset, just modify df and df1.

df <- data.frame(Group = rep(c("A", "B", "C"),  times = c(2, 4, 6)))
(df1 <- data.frame(Group = c("A","B","C"), Range = c("2-4","6-8","10-12")))

#   Group Range
# 1     A   2-4
# 2     B   6-8
# 3     C 10-12

res <- c()
for(i in 1:nrow(df1)){
    r <- strsplit(df1[i,]$Range, "-")[[1]]
    type <- r[1]:r[2]
    times <- length(df[df[1]==df1[i,]$Group])
    rep <- rep(type, as.integer(times/length(type)) 1)
    res <- c(res, rep[1:times])
}
cbind(df, res)

#    Group res
# 1      A   2
# 2      A   3
# 3      B   6
# 4      B   7
# 5      B   8
# 6      B   6
# 7      C  10
# 8      C  11
# 9      C  12
# 10     C  10
# 11     C  11
# 12     C  12
  • Related