Как использовать mutate вместо цикла for в R

#r #dplyr

Вопрос:

С помощью этого кода я получаю вектор tr , который должен быть новым столбцом df3 , если бы я мог использовать mutate df3 и использовать функцию calcTr для mutate .

Важно отметить, что последние 4 строки нового столбца не вычисляются ( NA ). Я подозреваю, что мне следует использовать mutate_at , но я не знаю, как это сделать.

Мой результат ( tr ) хорош. Пакет litteR предназначен только для вычисления тримеана (q1 2 * q2 q3) / 4 .

 library(tidyverse)
library(litteR) # to compute trimean
#> 
#> litteR version: 0.8.2
#> Type create_litter_project() to create a new project.
#> Type vignette("litteR-manual") to open the user manual.
#> Open the data file and check the presence of the column headers 'spatial_scale' and 'date'.
#> Open the settings file and check the settings.
#> Type litter() to start litteR.
set.seed(1234)

df <- tibble(date = rep(1:20, 3),
             country = c(rep('x', 20), rep('y', 20), rep('z', 20)),
             a = runif(60),
             b = runif(60),
             c = runif(60))

calcTr <- function(df, t1, gap){
  df2 <- df %>% filter(row(.) >= t1, row(.) < (t1   gap))
  trimean(as.vector(t(df2)), na.rm = FALSE)
}

cs <- c('x', 'y')

df2 <- df %>%
  filter(country %in% cs) %>%
  select(date, country, a) %>%
  group_by(country) %>% 
  pivot_wider(names_from = country, values_from = a) %>%
  ungroup() %>% select(-date)

gap <- 5
k <- nrow(df2) - (gap - 1)
tr <- NULL
for (t in 1:k) {
  tr <- c(tr, calcTr(df2, t, gap))
}

tr
#>  [1] 0.3530834 0.5268562 0.4862586 0.5348352 0.6095975 0.5608634 0.5037747
#>  [8] 0.5147133 0.4735918 0.4472276 0.3953627 0.4507762 0.3942934 0.3839828
#> [15] 0.3528786 0.3968370
Created on 2021-05-18 by the reprex package (v2.0.0)
 

Комментарии:

1. не могли бы вы исправить свое reprex включение library(tidyverse) , чтобы не было ошибок?

2. Спасибо. Это сделано.

Ответ №1:

Мы можем использовать map

 purrr::map_dbl(seq_len(k), ~ calcTr(df2, .x, gap))
 

Комментарии:

1. Это поразительно. Но как я могу использовать его для мутации df2 ?

2. @sbac На основе созданной вами функции каждый раз использует весь отфильтрованный набор данных. Итак, петля была бы лучше

3. Поэтому я должен использовать любительский ресурс: df2 <- bind_cols(df2, c(tr, rep(NA, 4)))