CallumH
CallumH

Reputation: 779

How to find index of value in a temporary dataframe in a loop in R

I am looking to add a column to a data frame with R which stores (as a character vector) the relative matched positions of certain values in the data frame against their relative row positions in temporary lookup data frames, which I generate on the fly in a loop.

I provide some dummy data, a stab-at-it solution that I haven't managed to get to work yet, and an explicit target column, all to assist. Thnx in advance.

Please note that i am not bound by a loop solution, I tried to use an apply approach but with less luck.

# the setup
band = data.frame(zep = c("page","plant","bonham","jones", "grant"), 
              age = c(36, 32, 32, 34, 45), 
              origin = c("heston", "westbrom", "redditch", "sidcup", "eastbourne"),
              alive = c(1,1,0,1,0), 
              rocked = c(1,1,1,1,0),
              active = c(59,  51, 18 ,55, 20), stringsAsFactors = F)

led_index is a data frame where I have 'all' my value/row positions stored and serves to be subsetted on each unique led_index$value as led_subbed

led_index = data.frame(value = c(rep("zep", 5), rep("origin", 5), rep("alive", 2), rep("rocked", 2)),
                   variable = c(band$zep, band$origin, 1,0,1,0),
                   stringsAsFactors = F)

not all of my 'band' columns will be subjected to this lookup process however, only those recorded in the vector 'subset_cols'

subset_cols = c("zep", "origin", "alive", "rocked")

I start my solution by instantiating a new column where I look to cyclically paste the relative positions found in subsets of led_index (which I name led_subbed) into

band$pass_string = character(nrow(band))

I then use a for loop to populate this new column with the row positions in four temporary led_subbed dataframes in the loop (however, my solution seems to index off of led_index rather than the four led_subbed's).

for(i in 1:length(subset_cols)){

sub_name = subset_cols[i]

# subset led_index
led_subbed = led_index[led_index$value == sub_name,]
for(j in 1:length(led_subbed$value)){

band$pass_string = paste(band$pass_string, as.integer(row.names(led_subbed))[match(led_subbed$variable, band[,names(band) == sub_name])])
}}

My target column should look like the following, where the row position is taken from each of the four led_subbed data frames that should be generated, one for each of the values in subset_cols.

band$my_target_pass_string = c("1 1 1 1",  "2 2 1 1", "3 3 2 1",  "4 4 1 1",  "5 5 2 2")

I hope this all makes sense?

Upvotes: 2

Views: 254

Answers (1)

Sotos
Sotos

Reputation: 51592

Here is an idea using match

led_index$ind <- with(led_index, ave(variable, value, FUN = seq))  

do.call(paste, as.data.frame(sapply(band[subset_cols], function(i)
                                led_index$ind[match(i, led_index$variable)])))

#[1] "1 1 1 1" "2 2 1 1" "3 3 2 1" "4 4 1 1" "5 5 2 2"

Upvotes: 1

Related Questions