data1=data.frame(Year=c(1,1,1,2,2,2,3,3,3),
"Group=c('A','A','A','B','B','B','C','C','C'),
"A=c(5,6,7,10,9,6,10,7,10),
"B=c(8,10,5,6,9,8,9,5,8),
"C=c(7,9,5,5,8,7,9,5,10))
data2=data.frame(Year=c(1,1,1,2,2,2,3,3,3),
"Group=c('A','A','A','B','B','B','C','C','C'),
"A=c(5,6,7,10,9,6,0,0,0),
"B=c(8,10,5,6,9,8,0,0,0),
"C=c(7,9,5,5,8,7,-99,-99,-99))
I have 'data1' and wish for 'data2' by using fifelse from data.table. The rule is, if Group = 'C', then columns 'A' and 'B' equal to zero and column 'C' equals to -99.
Using conditional replacement in data.table
,
data.table::setDT(data1)
data1[Group == "C",`:=`(A = 0, B = 0, C = -99)]
Note that the final dataframe is data1
( :=
updates by reference), not data2
Here, is one option with data.table
library(data.table)
setDT(data1)[Group == 'C', names(data1)[3:5] := .(0, 0, -99)]
data1
# Year Group A B C
#1: 1 A 5 8 7
#2: 1 A 6 10 9
#3: 1 A 7 5 5
#4: 2 B 10 6 5
#5: 2 B 9 9 8
#6: 2 B 6 8 7
#7: 3 C 0 0 -99
#8: 3 C 0 0 -99
#9: 3 C 0 0 -99
Or another option is set
v1 <- c(0, 0, -99)
nm1 <- c('A', 'B', 'C')
for(j in seq_along(nm1)) set(data1, i = which(data1$Group == 'C'), j= nm1[j], value = v1[j])
In base R
, we can do
data1[data1$Group == 'C', c('A', 'B', 'C')] <- list(0, 0, -99)
data1 <- structure(list(Year = c(1, 1, 1, 2, 2, 2, 3, 3, 3), Group = structure(c(1L,
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), .Label = c("A", "B", "C"), class = "factor"),
A = c(5, 6, 7, 10, 9, 6, 10, 7, 10), B = c(8, 10, 5, 6, 9,
8, 9, 5, 8), C = c(7, 9, 5, 5, 8, 7, 9, 5, 10)),
class = "data.frame", row.names = c(NA,
-9L))
Here is another approach using dplyr
and rbind
library(dplyr)
rbind(data1 %>% filter(Group != "C"),data1 %>% filter(Group == "C") %>% mutate(A=0, B=0,C=-99))
Output
Year Group A B C
1 1 A 5 8 7
2 1 A 6 10 9
3 1 A 7 5 5
4 2 B 10 6 5
5 2 B 9 9 8
6 2 B 6 8 7
7 3 C 0 0 -99
8 3 C 0 0 -99
9 3 C 0 0 -99
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.