Как создать столбец со средней разницей для подмножества столбцов?

Я хотел бы создать столбец со средним значением различий между подмножеством столбцов. Предположим, у меня есть следующий набор данных:

set.seed(123)
df <- data.frame( y = runif (1:10),
                  x1 = runif (1:10),
                  x2 = runif (1:10),
                  x3 = runif (1:10))
df[, "x1"][ df[, "x1"] < 0.5 ] <- NA
df[, "x3"][ df[, "x3"] > 0.7 ] <- NA

df
           y        x1        x2         x3
1  0.2875775 0.9568333 0.8895393         NA
2  0.7883051        NA 0.6928034         NA
3  0.4089769 0.6775706 0.6405068 0.69070528
4  0.8830174 0.5726334 0.9942698         NA
5  0.9404673        NA 0.6557058 0.02461368
6  0.0455565 0.8998250 0.7085305 0.47779597
7  0.5281055        NA 0.5440660         NA
8  0.8924190        NA 0.5941420 0.21640794
9  0.5514350        NA 0.2891597 0.31818101
10 0.4566147 0.9545036 0.1471136 0.23162579

Я хотел бы получить столбец со средним значением разницы между Xs и Y. Итак, в примере я хотел бы получить ((x1 - y)+(x2 - y)+(x3 - y))/( количество иксов). Это немного усложняется из-за пропущенных значений, не все строки будут вычисляться одинаково. Например, в строке 1 значение будет вычислено ((x1 - y)+(x2-y))/2, а в строке 7 должно быть просто вычислено (x2 - y)/1, поскольку имеется только одно значение. Как я могу получить эту колонку? Дайте мне знать, если вам нужно больше разъяснений.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
56
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Вы можете сделать:

library(dplyr)

df %>%
  rowwise() %>%
  mutate(result = mean(c_across(x1:x3) - y, na.rm = TRUE))

# A tibble: 10 × 5
# Rowwise: 
        y     x1    x2      x3  result
    <dbl>  <dbl> <dbl>   <dbl>   <dbl>
 1 0.288   0.957 0.890 NA       0.636 
 2 0.788  NA     0.693 NA      -0.0955
 3 0.409   0.678 0.641  0.691   0.261 
 4 0.883   0.573 0.994 NA      -0.0996
 5 0.940  NA     0.656  0.0246 -0.600 
 6 0.0456  0.900 0.709  0.478   0.650 
 7 0.528  NA     0.544 NA       0.0160
 8 0.892  NA     0.594  0.216  -0.487 
 9 0.551  NA     0.289  0.318  -0.248 
10 0.457   0.955 0.147  0.232  -0.0122

Большое спасибо за ответ. Это может быть неточно. Строка 1 должна быть ((0,957 - 0,288) + (0,890 - 0,288)) / 2 = 0,6355. И строка 7 должна вычислить (0,544 - 0,528)/1 = 0,016. Строка 10 должна вычислить ((0,955 - 0,457) + (0,147 - 0,457) + (0,232 - 0,457))/3 = 0,967. Не уверен, что код вычисляет.

Victor Shin 19.10.2022 01:31

Проверьте мое редактирование. Однако я не уверен, почему мой результат для 10 не совпадает с вашим.

Anoushiravan R 19.10.2022 01:54

Значение для последней строки не может быть 0,967, это -0,0122.

Anoushiravan R 19.10.2022 01:59

Вы правы, я просчитался. Я пытался отредактировать его, но stackoverflow не позволял мне это исправить. Я ценю ваш ответ! Большое спасибо.

Victor Shin 19.10.2022 02:13
Ответ принят как подходящий

Вы можете сделать это с помощью rowMeans в широком формате, чтобы решить проблемы NA:

rowMeans(df[c("x1","x2","x3")] - df[["y"]], na.rm=TRUE)

В конечном счете, я думаю, что данные x1/2/3 лучше хранить в длинном формате без NA, чтобы вы могли выполнять любые вычисления, используя логику group_by, не беспокоясь об исключении строк. Что-то вроде:

na.omit(cbind(rowid = seq_len(nrow(df)), stack(df[-1])))
#   rowid     values ind
#1      1 0.95683335  x1
#3      3 0.67757064  x1
#4      4 0.57263340  x1
#6      6 0.89982497  x1
#10    10 0.95450365  x1
#11     1 0.88953932  x2
#12     2 0.69280341  x2
# ...

Другое решение с использованием пакета pmean from kit:

df["result"] = kit::pmean(df[c("x1", "x2", "x3")]-df[["y"]], na.rm=TRUE)

           y        x1        x2         x3      result
1  0.2875775 0.9568333 0.8895393         NA  0.63560881
2  0.7883051        NA 0.6928034         NA -0.09550173
3  0.4089769 0.6775706 0.6405068 0.69070528  0.26061732
4  0.8830174 0.5726334 0.9942698         NA -0.09956581
5  0.9404673        NA 0.6557058 0.02461368 -0.60030754
6  0.0455565 0.8998250 0.7085305 0.47779597  0.64982730
7  0.5281055        NA 0.5440660         NA  0.01596054
8  0.8924190        NA 0.5941420 0.21640794 -0.48714407
9  0.5514350        NA 0.2891597 0.31818101 -0.24776464
10 0.4566147 0.9545036 0.1471136 0.23162579 -0.01220037

решение data.table

setDT(df)

df[, result := rowMeans(.SD, na.rm = T) - y, .SDcols = 2:4]

Результаты

           y      x1      x2       x3    result
 1: 0.287578 0.95683 0.88954       NA  0.635609
 2: 0.788305      NA 0.69280       NA -0.095502
 3: 0.408977 0.67757 0.64051 0.690705  0.260617
 4: 0.883017 0.57263 0.99427       NA -0.099566
 5: 0.940467      NA 0.65571 0.024614 -0.600308
 6: 0.045556 0.89982 0.70853 0.477796  0.649827
 7: 0.528105      NA 0.54407       NA  0.015961
 8: 0.892419      NA 0.59414 0.216408 -0.487144
 9: 0.551435      NA 0.28916 0.318181 -0.247765
10: 0.456615 0.95450 0.14711 0.231626 -0.012200

Другие вопросы по теме