有条件更新引用其他列

时间:2015-03-13 22:35:41

标签: r vectorization conditional-statements

我试图在R中对某些数据进行条件更新,这些数据的形状类似于下面给出的内容。

规则是,在类别Z的值== 0的情况下,将其设置为相同类型中的类别X的值。

作为一个R新手并且没有太多时间,我最终使用循环,因为我无法看到如何使用by()更新值,但我希望有一个更明显的解决方案。

Type    Category    Value
A       X           5
A       Y           2
A       Z           3
B       X           6
B       Y           2
B       Z           0
C       X           7
C       Y           2
C       Z           0

我想要的输出是:

Type    Category    Value
A       X           5
A       Y           2
A       Z           3 <- remains 3
B       X           6
B       Y           2
B       Z           6 <- updated to 6
C       X           7
C       Y           2
C       Z           7 <- updated to 7

提前致谢。

4 个答案:

答案 0 :(得分:5)

以下是使用dplyr包的解决方案:

library(dplyr)

# Assume your data frame is called "dat"
dat = dat %>% group_by(Type) %>%
  mutate(ValueNew = ifelse(Category=="Z" & Value==0, Value[Category=="X"], Value))

  Type Category Value ValueNew
1    A        X     5        5
2    A        Y     2        2
3    A        Z     3        3
4    B        X     6        6
5    B        Y     2        2
6    B        Z     0        6
7    C        X     7        7
8    C        Y     2        2
9    C        Z     0        7

答案 1 :(得分:5)

library(data.table)
 setDT(mydf)[, value1 := ifelse(Value != 0L & Category == "Z", 
                          Value, Value[Category == "X"]), by = Type]
mydf
#    Type Category Value value1
# 1:    A        X     5      5
# 2:    A        Y     2      2
# 3:    A        Z     3      3
# 4:    B        X     6      6
# 5:    B        Y     2      2
# 6:    B        Z     0      6
# 7:    C        X     7      7
# 8:    C        Y     2      2
# 9:    C        Z     0      7

答案 2 :(得分:2)

使用data.table

的另一个选项
library(data.table)
setDT(dat)[, Value := Value + Value[Category == 'X'] * 
               (Category == 'Z' & Value == 0L), by = Type][]
#    Type Category Value
#1:    A        X     5
#2:    A        Y     2
#3:    A        Z     3
#4:    B        X     6
#5:    B        Y     2
#6:    B        Z     6
#7:    C        X     7
#8:    C        Y     2
#9:    C        Z     7

答案 3 :(得分:1)

宽格式变异有时更直观:

library(dplyr)
library(tidyr)

df1 %>%
  spread(Category, Value) %>%
  mutate( Z = ifelse( Z == 0, X, Z)) %>%
  gather( Category, Value, -Type) %>%
  arrange(Type, Category, Value)

#   Type Category Value
# 1    A        X     5
# 2    A        Y     2
# 3    A        Z     3
# 4    B        X     6
# 5    B        Y     2
# 6    B        Z     6
# 7    C        X     7
# 8    C        Y     2
# 9    C        Z     7  

如果你可以使用宽格式,它只是枢轴和“Z规则”:

df1 %>%
  spread(Category, Value) %>%
  mutate( Z = ifelse( Z == 0, X, Z))

#   Type X Y Z
# 1    A 5 2 3
# 2    B 6 2 6
# 3    C 7 2 7