Command to create multiple columns in a data.frame conditioned to other 2 columns

Asked

Viewed 28 times

3

If I have a date.frame formed by the vectors:

V1<-c("A","B","C","D","B")
V2<-c("C","D","C","B","B")
V3<-c("D","D","C","A","A")
V4<-c("C","B","C","A","C")
G1<-c("C","C","A","A","B")
G2<-c("D","B","D","C","A")
G3<-c("A","B","B","C","A")
G4<-c("C","C","B","A","D")

dd<-data.frame(V1,V2,V3,V4,G1,G2,G3,G4)


 V1 V2 V3 V4 G1 G2 G3 G4
  A  B  B  A  A  D  B  C
  B  C  A  C  B  C  A  C
  B  D  D  C  D  A  D  D
  C  C  B  C  D  A  D  C
  C  B  C  D  B  B  C  A

I wanted to create 4 new columns with names R1,R2,R3,R4 that see if V1=G1, V2=G2 and so on, and take information 1 for true and 0 for false

I had it so, but I wanted a command to do them all at once.

dd$R1<-ifelse(dd$V1 == dd$G1, 1,0)

I tried to use it for but it wasn’t working.

2 answers

3

A basic R solution.

# primeiro determinar as colunas "V" com
# os mesmos números das colunas "G"
v <- grep("^V", names(dd))
g <- match(sub("^V", "", names(dd)[v]), sub("^G", "", names(dd)))

# agora quais têm valores iguais
# +(...) transforma valores lógicos em 0/1
R <- +(dd[v] == dd[g])

# e juntar tudo
colnames(R) <- paste0("R", v)
dd2 <- cbind(dd, R)
dd2
#  V1 V2 V3 V4 G1 G2 G3 G4 R1 R2 R3 R4
#1  A  C  D  C  C  D  A  C  0  0  0  1
#2  B  D  D  B  C  B  B  C  0  0  0  0
#3  C  C  C  C  A  D  B  B  0  0  0  0
#4  D  B  A  A  A  C  C  A  0  0  0  1
#5  B  B  A  C  B  A  A  D  1  0  1  0

2

You can make the comparison directly between the "G*" and "V" column sets*":

dd[grep("V", names(dd))] == dd[grep("G", names(dd))]
#>         V1    V2    V3    V4
#> [1,] FALSE FALSE FALSE  TRUE
#> [2,] FALSE FALSE FALSE FALSE
#> [3,] FALSE FALSE FALSE FALSE
#> [4,] FALSE FALSE FALSE  TRUE
#> [5,]  TRUE FALSE  TRUE FALSE

Since R encodes TRUE as 1 and FALSE as 0, to have the result as numbers can apply as.integer to the columns:

apply(dd[grep("V", names(dd))] == dd[grep("G", names(dd))], 2, as.integer)
#>      V1 V2 V3 V4
#> [1,]  0  0  0  1
#> [2,]  0  0  0  0
#> [3,]  0  0  0  0
#> [4,]  0  0  0  1
#> [5,]  1  0  1  0

Or, if you prefer to use ifelse:

ifelse(dd[grep("V", names(dd))] == dd[grep("G", names(dd))], 1,0)

Note that the columns are assumed to be in the correct order (1, 2, 3,...). If they are not, order them first:

dd <- dd[sort(names(dd))]

Browser other questions tagged

You are not signed in. Login or sign up in order to post.