-1

This is my df :

a <- data.frame(x1 = 1:3, x2 = 0, GF = c("Pelagic", "Demersal", "Cephalopod"), Pelagic = 6, Demersal = 7, Cephalopod = 8)

I have a list like this :

GF_list <- c("Pelagic", "Demersal", "Cephalopod")

I want to attribute to the x2 column the value corresponding to the GF of the line. So I do this

for (i in 1 : nrow(a)) {
  for (j in 1 : length(GF_list)) {
    if (a$GF[i] == GF_list[j]) { 
      a$x2[i] <- a[i,(ncol(a) + (- length(GF_list) + j))]  
    }}
}

But it takes a very long time ... (I have a large data frame)

Does it exist a faster way to applicate this attribution ? I think about a way which eliminates the first loop : "for (i in 1 : nrow(a))"

Thank you

Loulou
  • 703
  • 5
  • 17
  • Possible duplicate of https://stackoverflow.com/questions/6920441/index-values-from-a-matrix-using-row-col-indicies – akrun Jun 08 '17 at 04:23

3 Answers3

2

So you want to select a different column from each row? You can do complicated extractions from a data.frame with a numeric matrix. Here's how it might work

a$x2 <- a[cbind(1:nrow(a), match(GF_list, names(a)))]

The matrix has a column for row numbers and column numbers. We use match() to find the right column for each row.

MrFlick
  • 195,160
  • 17
  • 277
  • 295
1

One way is using apply row-wise and select the value of column from the GF column of that row.

a$x2 <- apply(a, 1, function(x) x[x[["GF"]]])
a
#  x1 x2         GF Pelagic Demersal Cephalopod
#1  1  6    Pelagic       6        7          8
#2  2  7   Demersal       6        7          8
#3  3  8 Cephalopod       6        7          8
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
1

Here is a solution which gives a numeric result:

i <- 1:nrow(a)
j <- which(a$GF %in% GF_list)
as.matrix(a[,(ncol(a)-length(GF_list)+1):ncol(a)])[cbind(i,j)]
jogo
  • 12,469
  • 11
  • 37
  • 42