R 引用其他列的条件更新

R 引用其他列的条件更新,r,vectorization,conditional-statements,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

我试图在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
类型类别值
A X 5
A Y 2

这里有一个使用
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

以宽格式进行变异有时更直观:

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  
如果您可以使用宽幅格式,那么这只是pivot和“Z规则”:


另一个选项使用
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
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
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