fill NA with previous column and specific condition with data.table in R



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








1















I have some of these table



 ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 NA 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 NA NA 114 NA 121 111 98 108 6
3: 10316168 88 78 NA 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 NA 121 121 114 111 NA NA NA 7
6: 10619463 42 NA NA NA NA NA NA NA NA 141 9
7: 10631362 174 NA 125 118 117 116 139 116 NA 104 10
8: 10725490 49 NA 175 NA 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 NA 169 140 127 112 NA 6
10: 10832134 10 178 NA NA 116 95 95 125 115 103 3


I try to fill this NAs with previous column value
(if V2 is NA fill with V1 value)



with condition which is limit (if limit is 3 just fill NA until V3 and leave with NAs)



so what I try to do is like this



 ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 114 114 114 114 121 111 98 108 6
3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
6: 10619463 42 42 42 42 42 42 42 42 42 141 9
7: 10631362 174 174 125 118 117 116 139 116 116 104 10
8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
10: 10832134 10 178 178 NA 116 95 95 125 115 103 3


Actual data is pretty big so it would be nice solve this problem with data.table
but other solution is still okay like dplyr or tidyr or other solution.










share|improve this question

















  • 1





    could you use dput() to post a sample of your data?

    – gfgm
    Nov 16 '18 at 12:48






  • 1





    And, you tried… ?

    – hrbrmstr
    Nov 16 '18 at 12:59











  • @hrbrmstr I don't think the linked question solves the problem as op is looking for a solution using data.table. Would post my answer but it got closed...

    – MRau
    Nov 16 '18 at 13:06











  • apologies, @MRau. re-opened

    – hrbrmstr
    Nov 16 '18 at 13:11











  • @snoram I filled NAs with this code data.frame(t(dt)) %>% fill(., names(.)) %>% t()) but problem is it fills all of NAs in need something for limit

    – zell kim
    Nov 16 '18 at 14:14

















1















I have some of these table



 ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 NA 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 NA NA 114 NA 121 111 98 108 6
3: 10316168 88 78 NA 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 NA 121 121 114 111 NA NA NA 7
6: 10619463 42 NA NA NA NA NA NA NA NA 141 9
7: 10631362 174 NA 125 118 117 116 139 116 NA 104 10
8: 10725490 49 NA 175 NA 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 NA 169 140 127 112 NA 6
10: 10832134 10 178 NA NA 116 95 95 125 115 103 3


I try to fill this NAs with previous column value
(if V2 is NA fill with V1 value)



with condition which is limit (if limit is 3 just fill NA until V3 and leave with NAs)



so what I try to do is like this



 ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 114 114 114 114 121 111 98 108 6
3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
6: 10619463 42 42 42 42 42 42 42 42 42 141 9
7: 10631362 174 174 125 118 117 116 139 116 116 104 10
8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
10: 10832134 10 178 178 NA 116 95 95 125 115 103 3


Actual data is pretty big so it would be nice solve this problem with data.table
but other solution is still okay like dplyr or tidyr or other solution.










share|improve this question

















  • 1





    could you use dput() to post a sample of your data?

    – gfgm
    Nov 16 '18 at 12:48






  • 1





    And, you tried… ?

    – hrbrmstr
    Nov 16 '18 at 12:59











  • @hrbrmstr I don't think the linked question solves the problem as op is looking for a solution using data.table. Would post my answer but it got closed...

    – MRau
    Nov 16 '18 at 13:06











  • apologies, @MRau. re-opened

    – hrbrmstr
    Nov 16 '18 at 13:11











  • @snoram I filled NAs with this code data.frame(t(dt)) %>% fill(., names(.)) %>% t()) but problem is it fills all of NAs in need something for limit

    – zell kim
    Nov 16 '18 at 14:14













1












1








1








I have some of these table



 ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 NA 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 NA NA 114 NA 121 111 98 108 6
3: 10316168 88 78 NA 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 NA 121 121 114 111 NA NA NA 7
6: 10619463 42 NA NA NA NA NA NA NA NA 141 9
7: 10631362 174 NA 125 118 117 116 139 116 NA 104 10
8: 10725490 49 NA 175 NA 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 NA 169 140 127 112 NA 6
10: 10832134 10 178 NA NA 116 95 95 125 115 103 3


I try to fill this NAs with previous column value
(if V2 is NA fill with V1 value)



with condition which is limit (if limit is 3 just fill NA until V3 and leave with NAs)



so what I try to do is like this



 ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 114 114 114 114 121 111 98 108 6
3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
6: 10619463 42 42 42 42 42 42 42 42 42 141 9
7: 10631362 174 174 125 118 117 116 139 116 116 104 10
8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
10: 10832134 10 178 178 NA 116 95 95 125 115 103 3


Actual data is pretty big so it would be nice solve this problem with data.table
but other solution is still okay like dplyr or tidyr or other solution.










share|improve this question














I have some of these table



 ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 NA 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 NA NA 114 NA 121 111 98 108 6
3: 10316168 88 78 NA 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 NA 121 121 114 111 NA NA NA 7
6: 10619463 42 NA NA NA NA NA NA NA NA 141 9
7: 10631362 174 NA 125 118 117 116 139 116 NA 104 10
8: 10725490 49 NA 175 NA 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 NA 169 140 127 112 NA 6
10: 10832134 10 178 NA NA 116 95 95 125 115 103 3


I try to fill this NAs with previous column value
(if V2 is NA fill with V1 value)



with condition which is limit (if limit is 3 just fill NA until V3 and leave with NAs)



so what I try to do is like this



 ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 114 114 114 114 121 111 98 108 6
3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
6: 10619463 42 42 42 42 42 42 42 42 42 141 9
7: 10631362 174 174 125 118 117 116 139 116 116 104 10
8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
10: 10832134 10 178 178 NA 116 95 95 125 115 103 3


Actual data is pretty big so it would be nice solve this problem with data.table
but other solution is still okay like dplyr or tidyr or other solution.







r dplyr data.table na tidyr






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 16 '18 at 12:45









zell kimzell kim

234




234







  • 1





    could you use dput() to post a sample of your data?

    – gfgm
    Nov 16 '18 at 12:48






  • 1





    And, you tried… ?

    – hrbrmstr
    Nov 16 '18 at 12:59











  • @hrbrmstr I don't think the linked question solves the problem as op is looking for a solution using data.table. Would post my answer but it got closed...

    – MRau
    Nov 16 '18 at 13:06











  • apologies, @MRau. re-opened

    – hrbrmstr
    Nov 16 '18 at 13:11











  • @snoram I filled NAs with this code data.frame(t(dt)) %>% fill(., names(.)) %>% t()) but problem is it fills all of NAs in need something for limit

    – zell kim
    Nov 16 '18 at 14:14












  • 1





    could you use dput() to post a sample of your data?

    – gfgm
    Nov 16 '18 at 12:48






  • 1





    And, you tried… ?

    – hrbrmstr
    Nov 16 '18 at 12:59











  • @hrbrmstr I don't think the linked question solves the problem as op is looking for a solution using data.table. Would post my answer but it got closed...

    – MRau
    Nov 16 '18 at 13:06











  • apologies, @MRau. re-opened

    – hrbrmstr
    Nov 16 '18 at 13:11











  • @snoram I filled NAs with this code data.frame(t(dt)) %>% fill(., names(.)) %>% t()) but problem is it fills all of NAs in need something for limit

    – zell kim
    Nov 16 '18 at 14:14







1




1





could you use dput() to post a sample of your data?

– gfgm
Nov 16 '18 at 12:48





could you use dput() to post a sample of your data?

– gfgm
Nov 16 '18 at 12:48




1




1





And, you tried… ?

– hrbrmstr
Nov 16 '18 at 12:59





And, you tried… ?

– hrbrmstr
Nov 16 '18 at 12:59













@hrbrmstr I don't think the linked question solves the problem as op is looking for a solution using data.table. Would post my answer but it got closed...

– MRau
Nov 16 '18 at 13:06





@hrbrmstr I don't think the linked question solves the problem as op is looking for a solution using data.table. Would post my answer but it got closed...

– MRau
Nov 16 '18 at 13:06













apologies, @MRau. re-opened

– hrbrmstr
Nov 16 '18 at 13:11





apologies, @MRau. re-opened

– hrbrmstr
Nov 16 '18 at 13:11













@snoram I filled NAs with this code data.frame(t(dt)) %>% fill(., names(.)) %>% t()) but problem is it fills all of NAs in need something for limit

– zell kim
Nov 16 '18 at 14:14





@snoram I filled NAs with this code data.frame(t(dt)) %>% fill(., names(.)) %>% t()) but problem is it fills all of NAs in need something for limit

– zell kim
Nov 16 '18 at 14:14












2 Answers
2






active

oldest

votes


















2














Using data.table's set() function:



Code



col <- paste0("V", 1:10)
for (i in 2:length(col))
rows <- which(is.na(dt[[col[i]]]) & dt[["limit"]] >= i)
set(
x = dt,
i = rows,
j = col[i],
value = dt[[col[i-1]]][rows]
)



Results



dt
ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
2: 10298462 74 114 114 114 114 114 121 111 98 108 6
3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
6: 10619463 42 42 42 42 42 42 42 42 42 141 9
7: 10631362 174 174 125 118 117 116 139 139 139 104 10
8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
10: 110832134 10 178 178 NA 116 95 95 125 115 103 3


Data



dt <- fread(" ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
10167638 89 NA 116 102 96 NA 106 116 NA 144 3
10298462 74 114 NA NA 114 NA 121 111 98 108 6
10316168 88 78 NA 77 72 96 NA 95 NA NA 4
10423491 118 77 NA 86 139 127 NA 103 93 84 2
10497492 12 154 NA 121 121 114 111 NA NA NA 7
10619463 42 NA NA NA NA NA NA NA NA 141 9
10631362 174 NA 125 118 117 116 139 116 NA 104 10
10725490 49 NA 175 NA 176 NA 139 123 140 141 5
10767348 140 106 174 162 NA 169 140 127 112 NA 6
110832134 10 178 NA NA 116 95 95 125 115 103 3")





share|improve this answer

























  • code is not working... it changes nothing

    – zell kim
    Nov 16 '18 at 14:54











  • @zellkim, I justed test it and it works as shown above. Have you loaded the data.table library?

    – sindri_baldur
    Nov 16 '18 at 14:56


















0














You can try a tidyverse



library(tidyverse)
dt %>%
gather(k, v, -ID, -limit) %>% # make df from wide to long
mutate(k = factor(k, levels = unique(k))) %>% # for correct spreading in the last step
group_by(ID) %>%
mutate(gr=ifelse(is.na(v), 1:n(), 0)) %>% # check where the NA's are
fill(v) %>% # update the values
mutate(v = ifelse(limit >= gr, v, NA)) %>% # change to NA back again accrding limit
select(-gr) %>%
spread(k, v) # backtransform to long
# A tibble: 10 x 12
# Groups: ID [10]
ID limit V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
<int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
1 10167638 3 89 89 116 102 96 NA 106 116 NA 144
2 10298462 6 74 114 114 114 114 114 121 111 98 108
3 10316168 4 88 78 78 77 72 96 NA 95 NA NA
4 10423491 2 118 77 NA 86 139 127 NA 103 93 84
5 10497492 7 12 154 154 121 121 114 111 NA NA NA
6 10619463 9 42 42 42 42 42 42 42 42 42 141
7 10631362 10 174 174 125 118 117 116 139 116 116 104
8 10725490 5 49 49 175 175 176 NA 139 123 140 141
9 10767348 6 140 106 174 162 162 169 140 127 112 NA
10 110832134 3 10 178 178 NA 116 95 95 125 115 103





share|improve this answer

























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53338205%2ffill-na-with-previous-column-and-specific-condition-with-data-table-in-r%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2














    Using data.table's set() function:



    Code



    col <- paste0("V", 1:10)
    for (i in 2:length(col))
    rows <- which(is.na(dt[[col[i]]]) & dt[["limit"]] >= i)
    set(
    x = dt,
    i = rows,
    j = col[i],
    value = dt[[col[i-1]]][rows]
    )



    Results



    dt
    ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
    1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
    2: 10298462 74 114 114 114 114 114 121 111 98 108 6
    3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
    4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
    5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
    6: 10619463 42 42 42 42 42 42 42 42 42 141 9
    7: 10631362 174 174 125 118 117 116 139 139 139 104 10
    8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
    9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
    10: 110832134 10 178 178 NA 116 95 95 125 115 103 3


    Data



    dt <- fread(" ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
    10167638 89 NA 116 102 96 NA 106 116 NA 144 3
    10298462 74 114 NA NA 114 NA 121 111 98 108 6
    10316168 88 78 NA 77 72 96 NA 95 NA NA 4
    10423491 118 77 NA 86 139 127 NA 103 93 84 2
    10497492 12 154 NA 121 121 114 111 NA NA NA 7
    10619463 42 NA NA NA NA NA NA NA NA 141 9
    10631362 174 NA 125 118 117 116 139 116 NA 104 10
    10725490 49 NA 175 NA 176 NA 139 123 140 141 5
    10767348 140 106 174 162 NA 169 140 127 112 NA 6
    110832134 10 178 NA NA 116 95 95 125 115 103 3")





    share|improve this answer

























    • code is not working... it changes nothing

      – zell kim
      Nov 16 '18 at 14:54











    • @zellkim, I justed test it and it works as shown above. Have you loaded the data.table library?

      – sindri_baldur
      Nov 16 '18 at 14:56















    2














    Using data.table's set() function:



    Code



    col <- paste0("V", 1:10)
    for (i in 2:length(col))
    rows <- which(is.na(dt[[col[i]]]) & dt[["limit"]] >= i)
    set(
    x = dt,
    i = rows,
    j = col[i],
    value = dt[[col[i-1]]][rows]
    )



    Results



    dt
    ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
    1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
    2: 10298462 74 114 114 114 114 114 121 111 98 108 6
    3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
    4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
    5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
    6: 10619463 42 42 42 42 42 42 42 42 42 141 9
    7: 10631362 174 174 125 118 117 116 139 139 139 104 10
    8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
    9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
    10: 110832134 10 178 178 NA 116 95 95 125 115 103 3


    Data



    dt <- fread(" ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
    10167638 89 NA 116 102 96 NA 106 116 NA 144 3
    10298462 74 114 NA NA 114 NA 121 111 98 108 6
    10316168 88 78 NA 77 72 96 NA 95 NA NA 4
    10423491 118 77 NA 86 139 127 NA 103 93 84 2
    10497492 12 154 NA 121 121 114 111 NA NA NA 7
    10619463 42 NA NA NA NA NA NA NA NA 141 9
    10631362 174 NA 125 118 117 116 139 116 NA 104 10
    10725490 49 NA 175 NA 176 NA 139 123 140 141 5
    10767348 140 106 174 162 NA 169 140 127 112 NA 6
    110832134 10 178 NA NA 116 95 95 125 115 103 3")





    share|improve this answer

























    • code is not working... it changes nothing

      – zell kim
      Nov 16 '18 at 14:54











    • @zellkim, I justed test it and it works as shown above. Have you loaded the data.table library?

      – sindri_baldur
      Nov 16 '18 at 14:56













    2












    2








    2







    Using data.table's set() function:



    Code



    col <- paste0("V", 1:10)
    for (i in 2:length(col))
    rows <- which(is.na(dt[[col[i]]]) & dt[["limit"]] >= i)
    set(
    x = dt,
    i = rows,
    j = col[i],
    value = dt[[col[i-1]]][rows]
    )



    Results



    dt
    ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
    1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
    2: 10298462 74 114 114 114 114 114 121 111 98 108 6
    3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
    4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
    5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
    6: 10619463 42 42 42 42 42 42 42 42 42 141 9
    7: 10631362 174 174 125 118 117 116 139 139 139 104 10
    8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
    9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
    10: 110832134 10 178 178 NA 116 95 95 125 115 103 3


    Data



    dt <- fread(" ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
    10167638 89 NA 116 102 96 NA 106 116 NA 144 3
    10298462 74 114 NA NA 114 NA 121 111 98 108 6
    10316168 88 78 NA 77 72 96 NA 95 NA NA 4
    10423491 118 77 NA 86 139 127 NA 103 93 84 2
    10497492 12 154 NA 121 121 114 111 NA NA NA 7
    10619463 42 NA NA NA NA NA NA NA NA 141 9
    10631362 174 NA 125 118 117 116 139 116 NA 104 10
    10725490 49 NA 175 NA 176 NA 139 123 140 141 5
    10767348 140 106 174 162 NA 169 140 127 112 NA 6
    110832134 10 178 NA NA 116 95 95 125 115 103 3")





    share|improve this answer















    Using data.table's set() function:



    Code



    col <- paste0("V", 1:10)
    for (i in 2:length(col))
    rows <- which(is.na(dt[[col[i]]]) & dt[["limit"]] >= i)
    set(
    x = dt,
    i = rows,
    j = col[i],
    value = dt[[col[i-1]]][rows]
    )



    Results



    dt
    ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
    1: 10167638 89 89 116 102 96 NA 106 116 NA 144 3
    2: 10298462 74 114 114 114 114 114 121 111 98 108 6
    3: 10316168 88 78 78 77 72 96 NA 95 NA NA 4
    4: 10423491 118 77 NA 86 139 127 NA 103 93 84 2
    5: 10497492 12 154 154 121 121 114 111 NA NA NA 7
    6: 10619463 42 42 42 42 42 42 42 42 42 141 9
    7: 10631362 174 174 125 118 117 116 139 139 139 104 10
    8: 10725490 49 49 175 175 176 NA 139 123 140 141 5
    9: 10767348 140 106 174 162 162 169 140 127 112 NA 6
    10: 110832134 10 178 178 NA 116 95 95 125 115 103 3


    Data



    dt <- fread(" ID V1 V2 V3 V4 V5 V6 V7 V8 V9 V10 limit
    10167638 89 NA 116 102 96 NA 106 116 NA 144 3
    10298462 74 114 NA NA 114 NA 121 111 98 108 6
    10316168 88 78 NA 77 72 96 NA 95 NA NA 4
    10423491 118 77 NA 86 139 127 NA 103 93 84 2
    10497492 12 154 NA 121 121 114 111 NA NA NA 7
    10619463 42 NA NA NA NA NA NA NA NA 141 9
    10631362 174 NA 125 118 117 116 139 116 NA 104 10
    10725490 49 NA 175 NA 176 NA 139 123 140 141 5
    10767348 140 106 174 162 NA 169 140 127 112 NA 6
    110832134 10 178 NA NA 116 95 95 125 115 103 3")






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 16 '18 at 15:15

























    answered Nov 16 '18 at 13:32









    sindri_baldursindri_baldur

    8,3651033




    8,3651033












    • code is not working... it changes nothing

      – zell kim
      Nov 16 '18 at 14:54











    • @zellkim, I justed test it and it works as shown above. Have you loaded the data.table library?

      – sindri_baldur
      Nov 16 '18 at 14:56

















    • code is not working... it changes nothing

      – zell kim
      Nov 16 '18 at 14:54











    • @zellkim, I justed test it and it works as shown above. Have you loaded the data.table library?

      – sindri_baldur
      Nov 16 '18 at 14:56
















    code is not working... it changes nothing

    – zell kim
    Nov 16 '18 at 14:54





    code is not working... it changes nothing

    – zell kim
    Nov 16 '18 at 14:54













    @zellkim, I justed test it and it works as shown above. Have you loaded the data.table library?

    – sindri_baldur
    Nov 16 '18 at 14:56





    @zellkim, I justed test it and it works as shown above. Have you loaded the data.table library?

    – sindri_baldur
    Nov 16 '18 at 14:56













    0














    You can try a tidyverse



    library(tidyverse)
    dt %>%
    gather(k, v, -ID, -limit) %>% # make df from wide to long
    mutate(k = factor(k, levels = unique(k))) %>% # for correct spreading in the last step
    group_by(ID) %>%
    mutate(gr=ifelse(is.na(v), 1:n(), 0)) %>% # check where the NA's are
    fill(v) %>% # update the values
    mutate(v = ifelse(limit >= gr, v, NA)) %>% # change to NA back again accrding limit
    select(-gr) %>%
    spread(k, v) # backtransform to long
    # A tibble: 10 x 12
    # Groups: ID [10]
    ID limit V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
    <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
    1 10167638 3 89 89 116 102 96 NA 106 116 NA 144
    2 10298462 6 74 114 114 114 114 114 121 111 98 108
    3 10316168 4 88 78 78 77 72 96 NA 95 NA NA
    4 10423491 2 118 77 NA 86 139 127 NA 103 93 84
    5 10497492 7 12 154 154 121 121 114 111 NA NA NA
    6 10619463 9 42 42 42 42 42 42 42 42 42 141
    7 10631362 10 174 174 125 118 117 116 139 116 116 104
    8 10725490 5 49 49 175 175 176 NA 139 123 140 141
    9 10767348 6 140 106 174 162 162 169 140 127 112 NA
    10 110832134 3 10 178 178 NA 116 95 95 125 115 103





    share|improve this answer





























      0














      You can try a tidyverse



      library(tidyverse)
      dt %>%
      gather(k, v, -ID, -limit) %>% # make df from wide to long
      mutate(k = factor(k, levels = unique(k))) %>% # for correct spreading in the last step
      group_by(ID) %>%
      mutate(gr=ifelse(is.na(v), 1:n(), 0)) %>% # check where the NA's are
      fill(v) %>% # update the values
      mutate(v = ifelse(limit >= gr, v, NA)) %>% # change to NA back again accrding limit
      select(-gr) %>%
      spread(k, v) # backtransform to long
      # A tibble: 10 x 12
      # Groups: ID [10]
      ID limit V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
      <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
      1 10167638 3 89 89 116 102 96 NA 106 116 NA 144
      2 10298462 6 74 114 114 114 114 114 121 111 98 108
      3 10316168 4 88 78 78 77 72 96 NA 95 NA NA
      4 10423491 2 118 77 NA 86 139 127 NA 103 93 84
      5 10497492 7 12 154 154 121 121 114 111 NA NA NA
      6 10619463 9 42 42 42 42 42 42 42 42 42 141
      7 10631362 10 174 174 125 118 117 116 139 116 116 104
      8 10725490 5 49 49 175 175 176 NA 139 123 140 141
      9 10767348 6 140 106 174 162 162 169 140 127 112 NA
      10 110832134 3 10 178 178 NA 116 95 95 125 115 103





      share|improve this answer



























        0












        0








        0







        You can try a tidyverse



        library(tidyverse)
        dt %>%
        gather(k, v, -ID, -limit) %>% # make df from wide to long
        mutate(k = factor(k, levels = unique(k))) %>% # for correct spreading in the last step
        group_by(ID) %>%
        mutate(gr=ifelse(is.na(v), 1:n(), 0)) %>% # check where the NA's are
        fill(v) %>% # update the values
        mutate(v = ifelse(limit >= gr, v, NA)) %>% # change to NA back again accrding limit
        select(-gr) %>%
        spread(k, v) # backtransform to long
        # A tibble: 10 x 12
        # Groups: ID [10]
        ID limit V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
        <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
        1 10167638 3 89 89 116 102 96 NA 106 116 NA 144
        2 10298462 6 74 114 114 114 114 114 121 111 98 108
        3 10316168 4 88 78 78 77 72 96 NA 95 NA NA
        4 10423491 2 118 77 NA 86 139 127 NA 103 93 84
        5 10497492 7 12 154 154 121 121 114 111 NA NA NA
        6 10619463 9 42 42 42 42 42 42 42 42 42 141
        7 10631362 10 174 174 125 118 117 116 139 116 116 104
        8 10725490 5 49 49 175 175 176 NA 139 123 140 141
        9 10767348 6 140 106 174 162 162 169 140 127 112 NA
        10 110832134 3 10 178 178 NA 116 95 95 125 115 103





        share|improve this answer















        You can try a tidyverse



        library(tidyverse)
        dt %>%
        gather(k, v, -ID, -limit) %>% # make df from wide to long
        mutate(k = factor(k, levels = unique(k))) %>% # for correct spreading in the last step
        group_by(ID) %>%
        mutate(gr=ifelse(is.na(v), 1:n(), 0)) %>% # check where the NA's are
        fill(v) %>% # update the values
        mutate(v = ifelse(limit >= gr, v, NA)) %>% # change to NA back again accrding limit
        select(-gr) %>%
        spread(k, v) # backtransform to long
        # A tibble: 10 x 12
        # Groups: ID [10]
        ID limit V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
        <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
        1 10167638 3 89 89 116 102 96 NA 106 116 NA 144
        2 10298462 6 74 114 114 114 114 114 121 111 98 108
        3 10316168 4 88 78 78 77 72 96 NA 95 NA NA
        4 10423491 2 118 77 NA 86 139 127 NA 103 93 84
        5 10497492 7 12 154 154 121 121 114 111 NA NA NA
        6 10619463 9 42 42 42 42 42 42 42 42 42 141
        7 10631362 10 174 174 125 118 117 116 139 116 116 104
        8 10725490 5 49 49 175 175 176 NA 139 123 140 141
        9 10767348 6 140 106 174 162 162 169 140 127 112 NA
        10 110832134 3 10 178 178 NA 116 95 95 125 115 103






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 16 '18 at 15:23

























        answered Nov 16 '18 at 13:27









        JimbouJimbou

        9,88911231




        9,88911231



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53338205%2ffill-na-with-previous-column-and-specific-condition-with-data-table-in-r%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            政党

            天津地下鉄3号線