0

Here is the code for my example dataset.

df = data.frame("group" =c(rep(1,5),rep(1,6),rep(2,4),rep(2,3)), "time" = c(rep(NA,5),seq(1,6),rep(NA,4),seq(1,3)), "p" = seq(1,18) )

  group time  p
1      1   NA  1
2      1   NA  2
3      1   NA  3
4      1   NA  4
5      1   NA  5
6      1    1  6
7      1    2  7
8      1    3  8
9      1    4  9
10     1    5 10
11     1    6 11
12     2   NA 12
13     2   NA 13
14     2   NA 14
15     2   NA 15
16     2    1 16
17     2    2 17
18     2    3 18

I would like to figure out how to apply a function by group to only the values that have time then append the result as a new column in the data frame. Here is my example function I would like to apply.

pfunc <- function(p){
  p+5
}

The output I am hoping to obtain would look as follows.

 group time  p new_p
1      1   NA  1    NA
2      1   NA  2    NA
3      1   NA  3    NA
4      1   NA  4    NA
5      1   NA  5    NA
6      1    1  6    11
7      1    2  7    12
8      1    3  8    13
9      1    4  9    14
10     1    5 10    15
11     1    6 11    16
12     2   NA 12    NA
13     2   NA 13    NA
14     2   NA 14    NA
15     2   NA 15    NA
16     2    1 16    21
17     2    2 17    22
18     2    3 18    23
1
  • library(data.table); setDT(df)[!is.na(time), p_new := pfunc(p)][] Commented Jul 10, 2020 at 17:32

1 Answer 1

2

You can try this:

library(dplyr)
df %>% group_by(group) %>%
  mutate(pnew=ifelse(is.na(time),time,time+5))

# A tibble: 18 x 4
# Groups:   group [2]
   group  time     p  pnew
   <dbl> <int> <int> <dbl>
 1     1    NA     1    NA
 2     1    NA     2    NA
 3     1    NA     3    NA
 4     1    NA     4    NA
 5     1    NA     5    NA
 6     1     1     6     6
 7     1     2     7     7
 8     1     3     8     8
 9     1     4     9     9
10     1     5    10    10
11     1     6    11    11
12     2    NA    12    NA
13     2    NA    13    NA
14     2    NA    14    NA
15     2    NA    15    NA
16     2     1    16     6
17     2     2    17     7
18     2     3    18     8

Update

You can use this function:

increase <- function(data,n)
{
  data %>% group_by(group) %>%
    mutate(pnew=ifelse(is.na(time),time,time+n)) -> result
  return(result)
}

increase(df,n = 10)

# A tibble: 18 x 4
# Groups:   group [2]
   group  time     p  pnew
   <dbl> <int> <int> <dbl>
 1     1    NA     1    NA
 2     1    NA     2    NA
 3     1    NA     3    NA
 4     1    NA     4    NA
 5     1    NA     5    NA
 6     1     1     6    11
 7     1     2     7    12
 8     1     3     8    13
 9     1     4     9    14
10     1     5    10    15
11     1     6    11    16
12     2    NA    12    NA
13     2    NA    13    NA
14     2    NA    14    NA
15     2    NA    15    NA
16     2     1    16    11
17     2     2    17    12
18     2     3    18    13

Update 2

I hope this helps:

df %>% group_by(group) %>% rowwise() %>% mutate(pnew=ifelse(is.na(time),NA,pfunc(time)))

# A tibble: 18 x 4
# Rowwise:  group
   group  time     p  pnew
   <dbl> <int> <int> <dbl>
 1     1    NA     1    NA
 2     1    NA     2    NA
 3     1    NA     3    NA
 4     1    NA     4    NA
 5     1    NA     5    NA
 6     1     1     6     6
 7     1     2     7     7
 8     1     3     8     8
 9     1     4     9     9
10     1     5    10    10
11     1     6    11    11
12     2    NA    12    NA
13     2    NA    13    NA
14     2    NA    14    NA
15     2    NA    15    NA
16     2     1    16     6
17     2     2    17     7
18     2     3    18     8
Sign up to request clarification or add additional context in comments.

4 Comments

instead of just adding the +5 is there a way we can incorporate actually using the created function. This is just a simplified example of my actual problem.
@MrClean Just give me a second, I will add something!
That still doesn't work, I need the solution to use the pfunc function that I created.
@MrClean I have added a new update. Please check and I hope it works.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.