基于行和列的复杂数据框值选择

时间:2018-12-22 19:39:43

标签: r dataframe

我需要在下面的数据集的每个上选择一些,然后计算总和

这是我的数据集的一部分。

    func draw(in view: MTKView) {

        if let currentDrawable = view.currentDrawable {
            let commandBuffer = self.commandQueue.makeCommandBuffer()

            if let myTexture = self.sourceTexture{

                let inputImage = CIImage(mtlTexture: myTexture, options: nil)

                self.vignetteEffect.setValue(inputImage, forKey: kCIInputImageKey)

                self.coreImageContext.render(self.vignetteEffect.outputImage!, to: currentDrawable.texture, commandBuffer: commandBuffer, bounds: inputImage!.extent, colorSpace: self.colorSpace)

                commandBuffer?.present(currentDrawable)

                commandBuffer?.commit()
            }
        }
    }

行是实验的试验,列是按时间顺序(> 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)。

例如,在第一次试用(第一行)中,我按下了“ b”,在3483 ms之后我按下了“ n”,依此类推。
这是我的数据框

key_duration

我需要一种方法来在每行(试用版)中选择所有“ b”值,计算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") 并将这些值打印在新列上,与“ m”相同。

我该怎么办?

我认为我需要一个类似于'apply()'的函数,但不计算行中的每个值,而只计算选定的值。

sum(key_duration)

谢谢

3 个答案:

答案 0 :(得分:0)

这是使用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”进行汇总。传播结果并重新加入您的初始数据。

答案 1 :(得分:0)

使用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_”开头的变量。其次,它将两个df从宽格式转换为长格式,并按列进行组合。第三,它根据行ID创建“ b”和“ m”值的摘要。最后,它将结果与原始df合并。

答案 2 :(得分:0)

您可以从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))