复杂的条件变异

时间:2016-12-10 01:30:14

标签: r conditional dplyr

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

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)]。例如,在group1中,当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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分:1)

这里是如何在基地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

答案 2 :(得分: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