Выбор сложных значений данных на основе строк и столбцов - PullRequest
0 голосов
/ 22 декабря 2018

Мне нужно выбрать несколько значений в каждой строке нижеуказанного набора данных и вычислить сумму .

Это часть моего набора данных.

> prova
   key_duration1 key_duration2 key_duration3 KeyPress1RESP KeyPress2RESP KeyPress3RESP
18          3483           364          3509             b             n             m
19          2367           818          3924             b             n             m
20          3775          1591           802             b             m             n
21           929          3059           744             n             b             n
22          3732           530          1769             b             n             m
23          3503          2011          2932             b             n             b
24          3684          1424          1688             b             n             m

Строки - это испытания эксперимента, а столбцы - нажатые клавиши во временной последовательности (keypressRESP) и количество времениключ до следующего (key_duration).

Так, например, в первом испытании (первая строка) я нажал «b», а через 3483 мс я нажал «n» и т. Д.
Это мой фрейм данных

structure(list(key_duration1 = c(3483L, 2367L, 3775L, 929L, 3732L, 
3503L, 3684L), key_duration2 = c(364L, 818L, 1591L, 3059L, 530L, 
2011L, 1424L), key_duration3 = c(3509, 3924, 802, 744, 1769, 
2932, 1688), KeyPress1RESP = structure(c(2L, 2L, 2L, 4L, 2L, 
2L, 2L), .Label = c("", "b", "m", "n"), class = "factor"), KeyPress2RESP = structure(c(4L, 
4L, 3L, 2L, 4L, 4L, 4L), .Label = c("", "b", "m", "n"), class = "factor"), 
    KeyPress3RESP = structure(c(3L, 3L, 4L, 4L, 3L, 2L, 3L), .Label = c("", 
    "b", "m", "n"), class = "factor")), row.names = 18:24, class = "data.frame")

Мне нужен метод для выбора в каждой строке (пробная версия) всех значений "b", вычисления sum(key_duration) и печати значений в новом столбце, то же самое для "m".

Как я могу сделать?

Я думаю, что мне нужна функция, похожая на 'apply ()', но без вычисления всех значений в строке, но только выбранных значений.

apply(prova[,1:3],1,sum)

Спасибо

Ответы [ 3 ]

0 голосов
/ 22 декабря 2018

С помощью tidyverse вы можете сделать:

bind_cols(df %>%
 select_at(vars(starts_with("KeyPress"))) %>%
 rowid_to_column() %>%
 gather(var, val, -rowid), df %>%
 select_at(vars(starts_with("key_"))) %>%
 rowid_to_column() %>%
 gather(var, val, -rowid)) %>%
 group_by(rowid) %>%
 summarise(b_values = sum(val1[val == "b"]),
           m_values = sum(val1[val == "m"])) %>%
 left_join(df %>%
            rowid_to_column(), by = c("rowid" = "rowid")) %>%
 ungroup() %>%
 select(-rowid)

  b_values m_values key_duration1 key_duration2 key_duration3 KeyPress1RESP KeyPress2RESP KeyPress3RESP
     <dbl>    <dbl>         <int>         <int>         <dbl> <fct>         <fct>         <fct>        
1    3483.    3509.          3483           364         3509. b             n             m            
2    2367.    3924.          2367           818         3924. b             n             m            
3    3775.    1591.          3775          1591          802. b             m             n            
4    3059.       0.           929          3059          744. n             b             n            
5    3732.    1769.          3732           530         1769. b             n             m            
6    6435.       0.          3503          2011         2932. b             n             b            
7    3684.    1688.          3684          1424         1688. b             n             m  

Сначала он разбивает df на две части: одну с переменными, начинающимися с «KeyPress», и одну с переменными, начинающимися с «key_».Во-вторых, он преобразует два dfs из широкоформатного формата в длинный и объединяет их по столбцам.В-третьих, он создает сводку для значений «b» и «m» в соответствии с идентификатором строки.Наконец, он объединяет результаты с оригинальным df.

0 голосов
/ 23 декабря 2018

Вы можете сделать логическую матрицу из столбцов KeyPress, умножить ее на подмножество key_duration и затем взять их rowSums.

prova$b_values <- rowSums((prova[, 4:6] == "b") * prova[, 1:3])
prova$n_values <- rowSums((prova[, 4:6] == "n") * prova[, 1:3])


   key_duration1 key_duration2 key_duration3 KeyPress1RESP KeyPress2RESP KeyPress3RESP b_values n_values
18          3483           364          3509             b             n             m     3483     364
19          2367           818          3924             b             n             m     2367     818
20          3775          1591           802             b             m             n     3775     802
21           929          3059           744             n             b             n     3059    1673
22          3732           530          1769             b             n             m     3732     530
23          3503          2011          2932             b             n             b     6435    2011
24          3684          1424          1688             b             n             m     3684    1424

Это работает, поскольку логические значения приводятся кчисловые 1 или 0, и сохраняются только значения для отдельных ключей.

Дополнительно: для обобщения вы можете вместо этого использовать функцию и tidyverse / purrr для сопоставления:

get_sums <- function(key) rowSums((prova[, 4:6] == key) * prova[, 1:3])
keylist <- list(b_values = "b", n_values = "n", m_values = "m")

library(tidyverse)
bind_cols(prova, map_dfr(keylist, get_sums))
0 голосов
/ 22 декабря 2018

Вот способ использования data.table.

library(data.table)
setDT(prova)

# melt
prova_long <-
  melt(
    prova[, idx := 1:.N],
    id.vars = "idx",
    measure.vars = patterns("^key_duration", "^KeyPress"),
    variable.name = "key",
    value.name = c("duration", "RESP")
  )

# aggregate
prova_aggr <- prova_long[RESP != "n", .(duration_sum = sum(duration)), by = .(idx, RESP)]

# spread and join
prova[dcast(prova_aggr, idx ~ paste0("sum_", RESP)), c("sum_b", "sum_m") := .(sum_b, sum_m), on = "idx"]
prova

Результат

#   key_duration1 key_duration2 key_duration3 KeyPress1RESP KeyPress2RESP KeyPress3RESP idx sum_b sum_m
#1:          3483           364          3509             b             n             m   1  3483  3509
#2:          2367           818          3924             b             n             m   2  2367  3924
#3:          3775          1591           802             b             m             n   3  3775  1591
#4:           929          3059           744             n             b             n   4  3059    NA
#5:          3732           530          1769             b             n             m   5  3732  1769
#6:          3503          2011          2932             b             n             b   6  6435    NA
#7:          3684          1424          1688             b             n             m   7  3684  1688

Идея состоит в том, чтобы преобразовать ваши данные в длинный формат, агрегируя по "RESP" для строки.Распространите результат и присоединитесь к вашим начальным данным.

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