Разделите столбцы на другие столбцы и себя в зависимости от индекса в dplyr - PullRequest
1 голос
/ 17 апреля 2020
library(dplyr)

set.seed(1)
df <- data.frame(dddt_a = sample(1:1000, 1000, replace=T),
                 dddt_b = sample(1:1000, 1000, replace=T),
                 dddt_c = sample(1:1000, 1000, replace=T),
                 dddt_d = sample(1:1000, 1000, replace=T),
                 index = as.character(sample(c("a", "b"), 1000, replace=T)))

Я хочу разделить каждый столбец на dddt_a или dddt_b в зависимости от индекса. Если индекс равен a, то разделите все столбцы, кроме индекса, на dddt_a, а если index==b, разделите все столбцы, кроме индекса, на dddt_b. Как это настроено сейчас, это только делит dddt_a на a, но не на другие столбцы (аналогично, если index==b).

df1 <- df %>% 
      mutate_at(.vars = vars(starts_with("dddt")),
                .funs = list(~ifelse(index=="a", ./dddt_a, ./dddt_b)))

head(df1)

     dddt_a dddt_b dddt_c dddt_d index
1 1.0000000    686    474    756     a
2 0.7388466      1    681    726     b
3 1.0000000    218    570    448     a
4 2.0086393      1    830    958     b
5 1.0000000    989    590    128     a
6 1.0000000    128    978    144     a

Обходной путь - сохранение переменной знаменателя снаружи, разделить данные для каждого индекса, разделить все и собрать обратно (здесь я запускал только для index==a). Тем не менее, это должно быть возможно в dplyr, я уверен ...?

ind_a <- df$dddt_a[df$index=="a"]

dfa <- df %>%
    filter(index=="a")%>%
    mutate_at(.vars = vars(starts_with("dddt")),
           .funs = ~ ./!!ind_a)

В связи с тем, что, кажется, та же проблема. В следующем шаге я хочу суммировать значения, опять же в зависимости от переменной index:

df2 <- df1 %>%
      mutate(SUMS = ifelse(index=="a", 
                   1+dddt_b+dddt_c+dddt_d,
                   1+dddt_a+dddt_c+dddt_d)) 

Однако, это суммирует все переменные ...

head(df2)
     dddt_a dddt_b dddt_c dddt_d index     SUMS
1 1.0000000    686    474    756     a 1917.000
2 0.7388466      1    681    726     b 1408.739
3 1.0000000    218    570    448     a 1237.000
4 2.0086393      1    830    958     b 1791.009
5 1.0000000    989    590    128     a 1708.000
6 1.0000000    128    978    144     a 1251.000

Но для первой строки, например, SUMS должно быть равно 1916:

rowSums(df2[1,2:4]) #the result should be 1916 not 1917
1916 

Спасибо за помощь.

Ответы [ 2 ]

0 голосов
/ 17 апреля 2020

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

library(dplyr)
df %>%
   mutate_at(vars(starts_with("dddt")),
        list(new = ~case_when(index=="a" ~ ./dddt_a, TRUE ~ ./dddt_b))) 
0 голосов
/ 17 апреля 2020

Создайте новый столбец после деления

library(dplyr)

df %>% 
  mutate_at(vars(starts_with("dddt")),
            list(new = ~ifelse(index=="a", ./dddt_a, ./dddt_b))) %>%
  head

 #  dddt_a dddt_b dddt_c dddt_d index dddt_a_new dddt_b_new dddt_c_new dddt_d_new
#1     836    686    474    756     a      1.000      0.821      0.567      0.904
#2     679    919    681    726     b      0.739      1.000      0.741      0.790
#3     129    218    570    448     a      1.000      1.690      4.419      3.473
#4     930    463    830    958     b      2.009      1.000      1.793      2.069
#5     509    989    590    128     a      1.000      1.943      1.159      0.251
#6     471    128    978    144     a      1.000      0.272      2.076      0.306

Если хотите, вы можете выбрать только "_new" столбцы или rename столбец "_new" для имен по вашему выбору.

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