加速data.frame操作而不是循环

时间:2018-06-15 02:28:11

标签: r for-loop dplyr

我在ticks: { //.. Other settings stepSize: 200, /* total/4 shows 0, 25%, 50%, 75%, 100% */ callback: function(value, index, values) { return ((value / 800) * 100) + '%'; } }

中有以下数据集
R

数据集是一个面板,其中dat <- data.frame(t = rep(seq(1, 5, 1),4), id = rep(c(rep("A",5), rep("B",5), rep("C",5), rep("D",5)), 1), x = 1:20, y = 51:70, h = c(rep(1,10), rep(0,10) ) ) require(dplyr) dat <- arrange(dat, t) 为时间变量,t为主题ID。我需要附加一行,我在id计算剩余主题的xy之和,并将其除以t的标准偏差其余主题的变量x。对于t的主题,此新行应显示为零。

例如,对于时间h == 0的主题A,操作为:t == 1。主题(6 * 56 + 11 * 61 + 16 * 66) / sd(c(6, 11, 16))在时间B的类似操作是t == 1。但是,对于主题(1 * 51 + 11 * 61 + 16 * 66) / sd(c(1, 11, 16))C,新行的特征仅为0。

没有循环的最快方法是什么?我相信D包是最快的,但我对它很新,而且我不确定如何处理它。在我的尝试中,我首先按时间分组,然后收集变量但我收到警告并删除了几个变量。我不确定如何为每个组选择变量。

dplyr

CONDITIONING

如何在前一个操作中包含一个条件,使得在下表中,仅在dat %>% group_by(t) %>% gather(key, value, -t) # Warning message: # attributes are not identical across measure variables; # they will be dropped 时计算操作。例如,对于第一行,我们将:0,因为主题cond == idBC都具有与其D不同的值(id是{ {1}})。对于第6行,操作为cond

A

建议的解决方案

(2*52 + 12*62 + 17*67) / sd(c(2,12,17))

效果很好,但部分工作,因为它会从dat <- data.frame(t = rep(seq(1, 5, 1),4), id = rep(c(rep("A",5), rep("B",5), rep("C",5), rep("D",5)), 1), x = 1:20, y = 51:70, h = c(rep(1,10), rep(0,10) ) ) dat <- arrange(dat, t) dat <- data.frame(dat, cond = c("B", "A", "A", "A", "A", "B", "C", "D", "A", "B", "D", "C", "A", "D", "C", "A", "A", "C", "C", "B") ) dat # t id x y h cond # 1 1 A 1 51 1 B # 2 1 B 6 56 1 A # 3 1 C 11 61 0 A # 4 1 D 16 66 0 A # 5 2 A 2 52 1 A # 6 2 B 7 57 1 B # 7 2 C 12 62 0 C # 8 2 D 17 67 0 D # 9 3 A 3 53 1 A # 10 3 B 8 58 1 B # 11 3 C 13 63 0 D # 12 3 D 18 68 0 C # 13 4 A 4 54 1 A # 14 4 B 9 59 1 D # 15 4 C 14 64 0 C # 16 4 D 19 69 0 A # 17 5 A 5 55 1 A # 18 5 B 10 60 1 C # 19 5 C 15 65 0 C # 20 5 D 20 70 0 B 乘以dat %>% filter(id == cond) %>% group_by(t) %>% mutate(new = h * ((sum(x *y) - (x * y))/map_dbl(row_number(), ~ sd(x[-.x])))) %>% bind_rows(dat %>% filter(id != cond)) 。相反,当条件不适用或分母的标准差为NaN时,我希望0 * Inf。非常感谢你!

1 个答案:

答案 0 :(得分:2)

按't'分组后,通过将'x'和'y'的乘积的sum与产品'x'和'y'(到')相加来创建'新'列。排除当前行产品)并通过循环遍历行索引(sd)获取'x'元素的row_number()除以用于排除当前行并乘以'h'所以除以它我们得到0,其中'h'为0。

library(tidyverse)
out <- dat %>% 
         group_by(t) %>% 
         mutate(new =  h * ((sum(x *y) - (x * y))/map_dbl(row_number(),
                                                     ~ sd(x[-.x]))))
head(out, 4)
# A tibble: 4 x 6
# Groups:   t [1]
#      t id        x     y     h   new
#  <dbl> <fct> <int> <int> <dbl> <dbl>
#1     1 A         1    51     1  413.
#2     1 B         6    56     1  233.
#3     1 C        11    61     0    0 
#4     1 D        16    66     0    0