Micromann Micromann - 24 days ago 6
R Question

How to use a list of objects' name to extract some columns from their associated dataframes using loop in R?

I EDITED my question



I created a list of names of 78 objects that I want to work with them in my code using the following lines of code. Eventually, I want to apply more or less the same functions to all of them in my work

total = len.part * len.report # This is equal to 78
nam.value <- list()
# Reporters and Partners are the name of countries
# Values is the name of my big dataframe which I am subsetting
for(i in Reporters) {
for (j in Partners) {
nam <- paste(i, "_VALUES_IMV_", j, sep = "")
nam.value <- c(nam.value, nam)
assign(nam, subset(Values, PARTNER == j & REPORTER == i & FLOW_LAB == "IMPORT") )
} }


The above code produces the list of names in the nam.value as well as 78 objects which are dataframes each of which has 14 columns. I am trying to use a loop to extract certain columns from these 78 dataframes using the names list that I just produced. Right now,
I have a quick and dirty solution to it which involves writing the name of all these objects down:

GB_VALUES_IMV_IN2 = GB_VALUES_IMV_IN[keeps]
GB_VALUES_IMV_EUEX2 = GB_VALUES_IMV_EUEX[keeps]
GB_VALUES_IMV_EUIN2 = GB_VALUES_IMV_EUIN[keeps]
IE_VALUES_IMV_IN2 = IE_VALUES_IMV_IN[keeps]
IE_VALUES_IMV_EUEX2 = IE_VALUES_IMV_EUEX[keeps]
IE_VALUES_IMV_EUIN2 = IE_VALUES_IMV_EUIN[keeps]
DE_VALUES_IMV_IN2 = DE_VALUES_IMV_IN[keeps]
DE_VALUES_IMV_EUEX2 = DE_VALUES_IMV_EUEX[keeps]
DE_VALUES_IMV_EUIN2 = DE_VALUES_IMV_EUIN[keeps]
..
..
..


But I am trying to use a shorter code and stop writing tens of lines of code by using a loop:

# The name of the columns that I want to keep and dropping the rest.
keeps = c("PRODUCT", "PERIOD","PARTNER", "INDICATOR_VALUE")
for (i in length(nam.value){
assign(nam.value[[i]], subset(nam.value[[i]], select = keeps) ) }


But I get the error:

Error in subset.default(nam.value[[i]], select = keeps) :
argument "subset" is missing, with no default


When I put the name of each object the above code, it works perfectly but for some reason it does not accept the names in the list. I don't need to use loops necessarily but trying with lapply and sapply, still I couldn't resolve my problem. Can anyone help?

Thank you

Answer

Using the data.table package it can be simplified to the following

Attempting to recreate your Values dataframe in data.table. If your dataframe is in a csv or database, you can either use the fread or as.data.table functions to import/convert the main Values table.

Values = data.table(
    'REPORTER'=c(rep('GB',3),rep('IE',3),rep('DE',3)),
    'PARTNER'=c(rep(c('IN2','EUEX2','EUIN2'),3)),
    'PRODUCT'=rep(c(1,2,3),3),
    'PERIOD'=rep(c(1,2,3)+3,3),
    'INDICATOR_VALUE'=rep(c(1,2,3)+6,3),
    'DUMMY'=c(1:9)
)

Creating a vector with the interaction between REPORTER and PARTNER :

info = with(Values,{interaction(REPORTER,PARTNER)})
info = levels(info)[info] # factor to string

Creating the keeps vector :

keeps = c("PRODUCT", "PERIOD","PARTNER", "INDICATOR_VALUE")

Loop through the interaction components

for( i in info ){
    info_list = unlist( strsplit(i,'\\.'))
    rep  = info_list[[1]]
    part = info_list[[2]]
    print( paste0(rep,'_VALUES_IMV_',part) )
    print( Values[ REPORTER == rep & PARTNER == part , .SD , .SDcols=keeps] )
}

Hope that helps get you in the direction you're looking for.