применить преобразование к определенным строкам и столбцам df на основе второго df - PullRequest
0 голосов
/ 24 мая 2018

У меня есть два огромных df (особенно первый), которые я здесь упрощаю.

library(tidyverse)
(thewhat <- tibble(sample = 1:10L, y= 1.0, z =2.0))

# A tibble: 10 x 3
   sample     y     z
    <int> <dbl> <dbl>
 1      1    1.    2.
 2      2    1.    2.
 3      3    1.    2.
 4      4    1.    2.
 5      5    1.    2.
 6      6    1.    2.
 7      7    1.    2.
 8      8    1.    2.
 9      9    1.    2.
10     10    1.    2.

(thewhere <- tibble(cond = c("a","a","b","c","a"),
     init_sample= c(1,3,4,5,7), 
     duration = c(1,2,2,1,3), 
     where = c(NA,"y","z","y","z")))

# A tibble: 5 x 4
  cond  init_sample duration where
  <chr>       <dbl>    <dbl> <chr>
1 a              1.       1. <NA> 
2 a              3.       2. y    
3 b              4.       2. z    
4 c              5.       1. y    
5 a              7.       3. z  

Я хочу "преобразовать" некоторые ячейки thewhat df в NA, основываясь на информации thewhere df.Важно отметить, что thewhat в широком формате, и я не хочу преобразовывать его в длинный формат (потому что у меня миллионы строк).

Я хочу преобразовать сэмплы, указанные в thewhere, с помощью init_sample до duration столбца, обозначенного where.(И если where - это NA, это означает, что оно применяется ко всем столбцам thewhat, за исключением sample; здесь y и z.)

Я создал df, NAs, который указывает, какие ячейки должны быть NA:

# table with the elements that should be replaced by NA
NAs <- filter(thewhere, cond=="a") %>% 
      mutate( sample = map2(init_sample, init_sample + duration - 1,seq)) %>% 
      unnest %>%
      select(where, sample)

Я пробовал разные подходы, и это наиболее близко, что я получил.В следующем mutate я сделал преобразование NA для одного столбца и мог вручную добавить остальные соответствующие столбцы, но в моем реальном сценарии у меня есть 30 столбцов.

# Takes into account the different columns but I need to manually add each relevant column
# and another case for mutate_all when the where is NA:
mutate(thewhat, y = if_else(sample %in% NAs$sample[NAs$where =="y"],  
        NA_real_, y  ))

Ожидаемый результатэто следующее:

# A tibble: 10 x 3
   sample     y     z
    <int> <dbl> <dbl>
 1      1   NA    NA
 2      2    1.    2.
 3      3   NA     2.
 4      4   NA     2.
 5      5    1.    2.
 6      6    1.    2.
 7      7    1.   NA 
 8      8    1.   NA 
 9      9    1.   NA 
10     10    1.    2.

Может быть, mutate_at или mutate_if могли бы работать здесь, но я не знаю как.Или какая-то функция map из purrr могла бы спасти меня, но мне не удалось заставить ее работать в этом случае.

(Брауни указывает, что решение остается в точке обзора, но я также могу житьс другим типом решения).

Спасибо, Бруно

1 Ответ

0 голосов
/ 24 мая 2018

На основании описания мы можем использовать map

library(tidyverse)
lst <- NAs %>% 
         split(.$where)
set_names(names(lst), names(lst)) %>%
     map_df(., ~ thewhat[[.x]] %>%
                 replace(., thewhat$sample %in% lst[[.x]]$sample, NA_real_) ) %>%
     bind_cols(thewhat %>%
                 select(sample), .)
# A tibble: 10 x 3
#   sample     y     z
#    <int> <dbl> <dbl>
# 1      1     1     2
# 2      2     1     2
# 3      3    NA     2
# 4      4    NA     2
# 5      5     1     2
# 6      6     1     2
# 7      7     1    NA
# 8      8     1    NA
# 9      9     1    NA
#10     10     1     2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...