2016-12-10 70 views
1

我在这个网站上经历了许多有条件的变异问题,但我的问题比那些更复杂。这是我的数据结构:复杂的条件变异

d = matrix(data = NA, ncol = 3, nrow = 9) 
d = as.data.frame(d) 
colnames(d) = c('group', 'type', 'v1') 
d$group = c(1,1,1,2,2,2,2,2,2) 
d$type = c(1,2,3,1,2,3,3,3,3) 
d$v1 = c(43,21,234,5,56,6,56,4,345) 


group type v1 
1 1 43 
1 2 21 
1 3 234 
2 1 5 
2 2 56 
2 3 6 
2 3 56 
2 3 4 
2 3 345 

它有两个分组变量:grouptype。我需要创建一个新的变量v2,使:

  • 每组

    ,如果type == 1v2 = 1

  • 每组

    ,如果type == 2v2 = [v1(type2) - v1(type1)]/[v1(type2) + v1(type1)]。例如,在组1中,当type == 2v2 = (21-43)/(21 + 43)

  • 每组

    ,如果type == 3,应用相同的功能v2 = [v1(type3) - v1(type1)]/[v1(type3) + v1(type1)]。例如,在1组,当type == 3v2 = (234 - 43)/(234 + 43)

我的数据集有超过200组。在每组中,类型3的频率也不同。

这里就是我所做的: 我创建公式的函数:

flsm = function(x, y){(x - y)/(x + y)} 

然后我尝试计算v2

d %>% group_by(group) %>% 
    mutate(v2 = ifelse(type == 2, 
         flsm(v1, type == 1[v1])), 
         ifelse(type == 3, flsm(v1, type == 1[v1])), 1) 

它返回以下警告:

Error: argument "no" is missing, with no default 
In addition: Warning messages: 
1: In is.na(e1) | is.na(e2) : 
    longer object length is not a multiple of shorter object length 
2: In `==.default`(c(1L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), 1[c(6.27, :longer object length is not a multiple of shorter object length 

我觉得我没有从正确的方法。任何想法如何计算v2

+0

看起来你每次调用'flsm'后都有一个额外的括号。它应该是mutate(lsm = ifelse(type == 2,flsm(v1,type == 1 [v1]), ifelse(type == 3,flsm(v1,type == 1 [v1]),1 )'。我不知道这是唯一的问题,但看看是否修复你的代码。 – eipi10

回答

2

你被v1尝试一些怪异的子集,索引1。通过你的描述去代替,就可以使用裸列名来引用变量组内和.$column_name指整列,它可以让你做的事:

d %>% group_by(group) %>% 
    mutate(v2 = ifelse(type == 1, 1, 
         flsm(v1, .$v1[.$group == unique(group) & .$type == 1]))) 

## Source: local data frame [9 x 4] 
## Groups: group [2] 
## 
## group type v1   v2 
## <int> <int> <int>  <dbl> 
## 1  1  1 43 1.00000000 
## 2  1  2 21 -0.34375000 
## 3  1  3 234 0.68953069 
## 4  2  1  5 1.00000000 
## 5  2  2 56 0.83606557 
## 6  2  3  6 0.09090909 
## 7  2  3 56 0.83606557 
## 8  2  3  4 -0.11111111 
## 9  2  3 345 0.97142857 
+0

谢谢!它工作得很好! – Marble

1

下面介绍如何在base R中完成它。从这里如果你想使用一个包来做同样的事情,它应该是直截了当的。

df1$v2 <- NA 

for(i in df1$gr){ 
    #in each group, if tye==1, v2=1 
    df1$v2[df1$tye==1 & df1$gr==i] <- 1 

    #in each group, if tye==2, v2=[v1(tye2)-v1(tye1)]/[v1(tye2)+v1(tye1)]. 
    df1$v2[df1$tye==2 & df1$gr==i] <- (df1$v1[df1$tye==2 & df1$gr==i] - df1$v1[df1$tye==1 & df1$gr==i])/(df1$v1[df1$tye==2 & df1$gr==i] 
                    +df1$v1[df1$tye==1 & df1$gr==i]) 



    #in each group, if tye==3, apply the same function v2=[v1(tye3)-v1(tye1)]/[v1(tye3)+v1(tye1)]. 
    df1$v2[df1$tye==3 & df1$gr==i] <- (df1$v1[df1$tye==3 & df1$gr==i] - df1$v1[df1$tye==1 & df1$gr==i])/(df1$v1[df1$tye==3 & df1$gr==i] 
              +df1$v1[df1$tye==1 & df1$gr==i]) 
} 
gr tye v1   v2 
1 1 1 43 1.00000000 
2 1 2 21 -0.34375000 
3 1 3 234 0.68953069 
4 2 1 5 1.00000000 
5 2 2 56 0.83606557 
6 2 3 6 0.09090909 
7 2 3 56 0.83606557 
8 2 3 4 -0.11111111 
9 2 3 345 0.97142857 
+0

谢谢!我应用你的代码,它返回以下警告:错误在d $ v2 [d $ tye == 3&d $ gr == i] < - (d $ v2 [d $ tye ==: 替换长度为零 – Marble

+0

@Marble当对原始数据运行时,代码会生成上面显示的结果。我认为错误是因为编辑后列名发生了变化。 –

+0

奇怪的是,前100个行工作正常,但随后的行是NAs。 – Marble

0

这里是data.table它分配一个选项到位

library(data.table) 
setDT(d)[, v2:= flsm(v1, d$v1[d$group==unique(group) & d$type ==1]) , group 
        ][type==1, v2 := 1][] 
# group type v1   v2 
#1:  1 1 43 1.00000000 
#2:  1 2 21 -0.34375000 
#3:  1 3 234 0.68953069 
#4:  2 1 5 1.00000000 
#5:  2 2 56 0.83606557 
#6:  2 3 6 0.09090909 
#7:  2 3 56 0.83606557 
#8:  2 3 4 -0.11111111 
#9:  2 3 345 0.97142857