BiXiC
BiXiC

Reputation: 973

subset dataframe variables through part of names

Suppose I have a data frame that contains these series and something else.

Where Ru and Uk are country codes.

Date CPI.Ru CPI.g.Ru CPI.s.Ru CPI.Uk CPI.g.Uk CPI.s.Uk
Q4-1990 61.4    66.4    67.5    72.2    68.2    32.4
Q1-1991 61.3    67.0    68.0    72.6    68.8    33.2
Q2-1991 61.4    67.5    68.1    73.2    69.5    35.1
Q3-1991 61.7    68.7    68.9    73.7    70.6    35.9
Q4-1991 62.3    68.4    69.3    74.3    71.9    38.2
Q1-1992 62.3    69.7    69.6    74.7    72.9    39.2
Q2-1992 62.1    70.3    70.0    75.3    73.7    40.6
Q3-1992 62.2    71.4    70.5    75.3    74.1    41.2
Q4-1992 62.5    71.1    70.9    75.7    74.3    44.0

I want to subset dataframe by country and then do something with this series.

For example I want to divide CPI index for each country by its first element.

How can I do it in cycle or maybe with apply function?

countries <- c("Ru","Uk")
for (i in countries)
{dataFrameName$CPI.{i} <- dfName$CPI.{i}/dfName$CPI.{i}[1]}

What should I write instead of {i}?

Upvotes: 0

Views: 60

Answers (2)

Backlin
Backlin

Reputation: 14842

$ only accept fixed column names. To select columns based on an expression you can instead use double brackets:

countries <- c("Ru", "Uk")
for (i in countries){
    x <- paste0("CPI.", i)
    dfName[[x]] <- dfName[[x]]/dfName[[x]][1]
}

Upvotes: 1

talat
talat

Reputation: 70266

This is not a loop, but if your data is always of the same form for each country, so that each country has 3 columns, and you always want to operate on the first column per country, you could try this:

sub <- df[,seq(2,ncol(df), 3)]   #create a subsetted data.frame containing the CPI index per country

apply(sub, 2, function(x) x/x[1])    #then use apply to operate on each column


#         CPI.Ru   CPI.Uk
# [1,] 1.0000000 1.000000
# [2,] 0.9983713 1.005540
# [3,] 1.0000000 1.013850
# [4,] 1.0048860 1.020776
# [5,] 1.0146580 1.029086
# [6,] 1.0146580 1.034626
# [7,] 1.0114007 1.042936
# [8,] 1.0130293 1.042936
# [9,] 1.0179153 1.048476

Upvotes: 1

Related Questions