2017-07-26 123 views
3

以下是我的示例数据框df,其中包含许多变量,其中C是其中一个变量中列的长度。R中的递减乘法

ID C 
1 0 
2 1.47349678 
3 0 
4 0 
5 0 
6 0 
7 0 
8 0 
9 0 
10 0 
11 0 
12 0 
13 0 
14 0 
16 1.987 
17 0 
18 0 
19 0 
20 0 
21 0 
22 0 
23 0 
24 0 
25 0 
26 0 
27 0 

我需要创建另一个变量C_C其中它由C产物和递减因子的0.1
必须仅对C_C的值的计数10进行乘法运算,其值为C,而不是0。结果也必须从下一个数据点存储。即如果C !=0Id ==2,则产品必须从ID==3
如果有非零数字后不到10连续零将计数只是重置为C新的值存储找到,如果发现没有进一步的数据乘法将停止。

预期结果

ID C    C_C 
    1 0    0 
    2 1.47349678  0 
    3 0    1.47349678 
    4 0    1.326147102 
    5 0    1.178797424 
    6 0    1.031447746 
    7 0    0.884098068 
    8 0    0.73674839 
    9 0    0.589398712 
    10 0    0.442049034 
    11 0    0.294699356 
    12 0    0.147349678 
    13 0    0 
    14 0    0 
    16 1.987   0 
    17 0    1.987 
    18 0    1.7883 
    19 0    1.5896 
    20 0    1.3909 
    21 0    1.1922 
    22 0    0.9935 
    23 0    0.7948 
    24 0    0.5961 
    25 0    0.3974 
    26 0    0.1987 
    27 0    0 

从所需的结果观察
1.价值C这是不0是enocunter在ID = 2,因此产品被从ID == 3C_C3存储。
2. C_C3 == C2 * 1C_C4 == C2*0.9,C_C5 == C2 * 0.8 ...... C_C12 == C*0.1, C_C13 == C2 *0
3.同样C_C17 == C16 * 1C_C18 == C16*0.9C_C19 == C16 *0.8,... C_C26 == C16 *0.1C_C27 == C16*0

谢谢!

+0

如果在一个非零数字之后连续的零点少于10个,计数值才会重置? –

+0

@RonakShah是的,我忘了提到这一点。计数应重置“C”的新值以进行乘法运算。 – Tareva

回答

3

随着dplyr:

library(dplyr) 
df$group = cumsum(dt$C>0) 
df = df %>% group_by(group) %>% mutate(value=sum(C)) %>% 
    mutate(n=1.1-0.1*(row_number()-1)) %>% mutate(n=ifelse(n<0|value==0|n==1.1,0,n)) %>% 
    mutate(C_C = n*value) %>% ungroup() %>% select(-n,-group,-value) %>% as.data.frame() 

    ID  C C_C 
1 1 0.000 0.0000 
2 2 1.473 0.0000 
3 3 0.000 1.4735 
4 4 0.000 1.3261 
5 5 0.000 1.1788 
6 6 0.000 1.0314 
7 7 0.000 0.8841 
8 8 0.000 0.7367 
9 9 0.000 0.5894 
10 10 0.000 0.4420 
11 11 0.000 0.2947 
12 12 0.000 0.1473 
13 13 0.000 0.0000 
14 14 0.000 0.0000 
15 16 1.987 0.0000 
16 17 0.000 1.9870 
17 18 0.000 1.7883 
18 19 0.000 1.5896 
19 20 0.000 1.3909 
20 21 0.000 1.1922 
21 22 0.000 0.9935 
22 23 0.000 0.7948 
23 24 0.000 0.5961 
24 25 0.000 0.3974 
25 26 0.000 0.1987 
26 27 0.000 0.0000 
+0

感谢您的解决方案,但'C_C3 == C2 * 1',但根据您的代码其'C_C3 == C * 0.9'。 – Tareva

+0

对不起,我忽略了。通过设置1更正为1.1 – Florian

+0

谢谢。完美的作品。 – Tareva

2

sapply有点漫长的过程,从基础R

vals <- which(df$C != 0) 
values <- c(sapply(df$C[vals], function(x) x * rev(seq(0.1, 1.0, 0.1)))) 
inds <- c(sapply(vals + 1, function(x) seq(x, x+9))) 
df$C_C <- 0 
df$C_C[inds] <- values 
df$C_C 

# [1] 0.0000000 0.0000000 1.4734968 1.3261471 1.1787974 1.0314477 0.8840981 
# [8] 0.7367484 0.5893987 0.4420490 0.2946994 0.1473497 0.0000000 0.0000000 
#[15] 0.0000000 1.9870000 1.7883000 1.5896000 1.3909000 1.1922000 0.9935000 
#[22] 0.7948000 0.5961000 0.3974000 0.1987000 0.0000000 

在这里,我们先找出指标这不等于0(vals),获得各自的值(df$C[vals]),对于每个值我们乘以1.0,0.9,0.8 .....等等。我们现在拥有我们需要的所有values,现在我们使用seq函数来生成这些values我们生成其各自的索引(inds)。我们现在可以在其各自的索引(inds)上指定values,并将剩余值赋值为0。

+0

感谢您的解决方案!,我的数据帧大约有850K个数据点,你的代码正在执行150K左右的数据点,但对于我的数据帧为850K,它抛出了一个列长度不等的错误。 – Tareva