Как использовать условие со строками в кадре данных (средневзвешенное значение, язык R)? - PullRequest
0 голосов
/ 03 марта 2019

Мне нужно вычислить средневзвешенное значение каждой строки в кадре данных, где: Кто-нибудь знает, как это сделать с использованием языка R?С уважением

t1 <- c(1, 2, 4, 6, 7, 9)
t2 <- c(6, 6, 5, 3, 3, 7)
df <- data.frame(t1 = t1, t2=t2, stringsAsFactors = FALSE)

if value <= 5 , weight is 1
if value > 5 and <= 8 , weight is 2
if value > 8 , weight is 3

Ответы [ 3 ]

0 голосов
/ 03 марта 2019

Базовое решение R, функция findInterval выполняет основную часть.Затем умножьте результат на df и получите значение строки.

t1 <- c(1, 2, 4, 6, 7, 9)
t2 <- c(6, 6, 5, 3, 3, 7)
df <- data.frame(t1 = t1, t2=t2, stringsAsFactors = FALSE)

cp <- c(-Inf, 5, 8, Inf)

Edit.

Если весовые коэффициенты нормализованы для суммирования до 1, топравильный ответ будет любым из следующих двух.

wt <- sapply(df, findInterval, cp)
rowSums(df*(wt/apply(wt, 1, sum)))
#[1] 4.333333 4.666667 4.666667 5.000000 5.666667 8.200000

sapply(1:nrow(df), function(i)
  weighted.mean(df[i,], sapply(df, findInterval, cp)[i,]))
#[1] 4.333333 4.666667 4.666667 5.000000 5.666667 8.200000

Эти результаты теперь равны результатам в других ответах.

0 голосов
/ 03 марта 2019

Если вы хотите умножить на вес, а затем разделить на их сумму (равна weighted.mean функция в R):

df %>%
  mutate_at(vars(t1, t2),
            list(weights = ~ case_when(. <= 5 ~ 1,
                                       . > 5 & . <= 8 ~ 2,
                                       TRUE ~ 3))) %>%
  mutate(rowMeanWeighted = rowSums(.[, 1:2] * .[, 3:4]) / rowSums(.[, 3:4])) %>%
  select(-contains("weights"))

Выход:

  t1 t2 rowMeanWeighted
1  1  6        4.333333
2  2  6        4.666667
3  4  5        4.500000
4  6  3        5.000000
5  7  3        5.666667
6  9  7        8.200000
0 голосов
/ 03 марта 2019

Решение, использующее tidyverse для расчета средневзвешенного значения для каждой строки.

library(tidyverse)

df2 <- df %>%
  # Add row numbers
  rowid_to_column() %>%
  # Convert to long format
  gather(Group, Value, -rowid) %>%
  # Assign weight
  mutate(Weight = case_when(
    Value <= 5                   ~1,
    Value >  5 & Value <= 8      ~2,
    Value > 8                    ~3,
    TRUE                         ~NA_real_
  )) %>%
  # Calculated weighted average
  group_by(rowid) %>%
  summarize(Weighted_Mean = weighted.mean(Value, Weight)) %>%
  ungroup()
df2
#   rowid Weighted_Mean
#   <int>         <dbl>
# 1     1          4.33
# 2     2          4.67
# 3     3          4.5 
# 4     4          5   
# 5     5          5.67
# 6     6          8.2 
...