мурлыкать итерацию или цикл по всем столбцам (аналогично функции, которая считает и суммирует или вычитает переменные) - PullRequest
1 голос
/ 01 ноября 2019

Я хотел бы найти здесь некоторые идеи, чтобы решить очень практическую проблему. Допустим, у меня есть две временные точки (w0 и w1), и я хочу вычесть (или сложить) все конкретные парные значения. Мера 1 в момент времени 1 и мера 1 в момент времени 2, мера 2 в момент времени 1 и мера 2 в момент времени 2.

Я более знаком со средой, изменяющей положение (желательно мурлыкать), и это код, который у меня естьдля моделирования реального набора данных

Любая охота нужна. Спасибо

library(tidyverse)
ds <- data.frame(w0_1=rnorm(10,1,2),
                 w0_2=rnorm(10,3,3),
                 w0_3=rnorm(10,3,2),
                 w1_1=rnorm(10,2,1),
                 w1_2=rnorm(10,3,3),
                 w1_3=rnorm(10,5,4))


ds %>% 
  summarise(dif_1 = mean(w0_1, na.rm=T)-mean(w1_1, na.rm=T))

ds %>% 
  summarise(dif_2 = mean(w0_2, na.rm=T)-mean(w1_2, na.rm=T))

Кстати, я знаю, что следующий код не будет работать, но это обоснование моего вопроса

for (i in 1:3) {
  ds %>% 
    summarise(dif_1 = mean(w0_[[i]], na.rm=T)-mean(w1_[[i]], na.rm=T))
}

Ответы [ 3 ]

2 голосов
/ 01 ноября 2019

Используя данные @ fmarm, мы используем не аккуратный подход:

(ds.mean <- colMeans(ds, na.rm=TRUE))
#   w0_1  w0_2  w0_3  w1_1  w1_2  w1_3 
#  1.264 3.747 2.733 2.121 3.402 5.574 
(ds.diff <- ds.mean[paste0("w0_", 1:3)] - ds.mean[paste0("w1_", 1:3)])
#     w0_1    w0_2    w0_3 
#  -0.8563  0.3441 -2.8412 

Если число w0 известно (в данном случае 3), то это проще:

(ds.diff <- ds.mean[1:3] - ds.mean[4:6])
#    w0_1    w0_2    w0_3 
# -0.8563  0.3441 -2.8412
1 голос
/ 01 ноября 2019

Для подхода purrr вы можете сначала разбить кадр данных на группы по 3, а затем использовать pmap_dbl()

library(purrr)
library(dplyr)

split.default(ds, (seq_along(ds)-1) %/% 3) %>%
  pmap_dbl(~ mean(.x - .y))

      w0_1       w0_2       w0_3 
-0.8563246  0.3441249 -2.8411739 

В ответ на комментарии ОП о полном наборе данных, имеющем 12 переменных одновременно. точки, и при условии, что переменные в порядке и не имеют пропущенных значений:

dataset %>% 
  select(starts_with("w4"), starts_with("w0")) %>%
  split.default((seq_along(.)-1) %/% (ncol(.)/2)) %>%
  pmap_dbl(~ mean(.x - .y))
1 голос
/ 01 ноября 2019

Вот решение, возможно, есть что-то попроще

ds %>% pivot_longer(names(ds),names_to=c('g0','g1'),names_pattern= '^(w.*)_(.*)') %>% # convert to long format
       group_by(g0,g1) %>% # group by g0 = (w0 or w1) and g1=(1,2,3)
       summarise(value=mean(value,na.rm=TRUE))   %>% # get mean by group
       pivot_wider(names_from=g0,values_from=value) %>% # pivot to get three lines
       mutate(dif = w0-w1) %>% # difference of mean by group
       select(g1,dif) %>% # keep only useful columns
       pivot_wider(names_from=g1,names_prefix='dif_',values_from=dif) #pivot again to have everything in one line

# A tibble: 1 x 3
#  dif_1 dif_2 dif_3
#  <dbl> <dbl> <dbl>
#1 -0.856 0.344  -2.84

Вы не установили начальное значение, поэтому наши результаты могут отличаться, я использовал set.seed(1).

Нет цикла или необходимостиидея purrr, идея в том, что если вам нужно делать циклы, это означает, что ваши данные должны быть изменены, используя pivot_longer, например,

. Я предлагаю вам запустить его шаг за шагом, чтобы увидеть, что код делает в каждой строке,каждый шаг - это базовое преобразование.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...