Reputation: 25
I have dataframe StateList with 2 columns STATE and Month. I have another data frame StateTemp
with the average temp of each state for each month in the US. I am trying to create third column StateList$Temp
which will get the temperature from StateTemp based upon the values of StateList$State
and StateList$Month
indexed into StateTemp. Please see below for reference. Any help is greatly appreciated.
head(StateList)
STATE Month
1 FL Jan
3 MD Jan
4 MD Jan
5 WI Jan
6 UT Jan
12 NY Jan
Second object:
head(StateTemp)
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
AL 44.29 48.04 55.47 61.99 69.89 76.75 79.87 79.04 73.88 63.08 54.10 46.85
AZ 42.27 46.24 51.03 57.63 66.01 75.51 80.19 78.50 72.52 61.61 49.64 42.51
AR 38.48 43.76 51.96 60.36 68.62 76.40 80.57 79.26 72.26 61.47 50.32 41.59
CA 45.14 48.51 51.76 56.50 63.11 70.18 75.32 74.62 69.97 61.56 51.17 44.98
CO 23.71 28.34 35.57 43.06 52.50 62.15 67.60 65.75 57.72 46.64 33.51 25.20
CT 25.96 28.43 36.94 47.07 57.77 66.29 71.52 69.77 61.68 50.60 41.43 31.13
Upvotes: 1
Views: 869
Reputation: 25
Thank you everyone for your responses. BondedDust that was awesome. Vaetchen your solution is great too. After I posted I managed to get some code with a for loop working as below. BondedDust's solution is much more elegant than mine. I need to get better with the [ function. hrbrmstr I shuld have expressed it more clearly I was not reshaping StateTemp but adding a third column to a two column dataframe StateList with 150K rows. The StateTemp is basically a lookup table to populate it. As usual there seems to be a over hundred ways to skin a cat in R.
`for (i in 1:nrow(StateList)) { StateList$Temp[i] <-StateTemp[StateList$STATE[i],StateList$Month[i]] }'
Upvotes: 0
Reputation: 7659
If you like a more "traditional" approach:
# state list that fits to the temparature data
StateList <- data.frame( STATE = c( "AL", "CT", "CA", "AZ", "CO", "AR" ),
Month = c( "Jan", "Feb", "Mar", "Jan", "Jan", "Feb" ),
stringsAsFactors = FALSE )
# create column for temperature values
StateList$Temp <- 0
# fill it row by row
for( i in 1 : length( StateList$STATE ) )
{
s <- StateList[ i, 1 ] # get state name
m <- StateList[ i, 2 ] # get month name
# find in matrix:
StateList$Temp[ i ] <- StateTemp[ rownames( StateTemp ) == s,
colnames( StateTemp ) == m ]
}
# I guess this is what you want to see:
StateList
STATE Month Temp
1 AL Jan 44.29
2 CT Feb 28.43
3 CA Mar 51.76
4 AZ Jan 42.27
5 CO Jan 23.71
6 AR Feb 43.76
Upvotes: 0
Reputation: 263481
Try this. It uses the ability of a column oriented matrix to index a dimensione object using such an object as a single argument to the "[" function:
> StateList$Temp <- StateTemp[ with( StateList, cbind( STATE, Month) ) ]
> StateList
STATE Month Temp
1 FL Jan 44.29
3 MD Jan 42.27
4 MD Jan 42.27
5 WI Jan 23.71
6 UT Jan 45.14
12 NY Jan 38.48
Upvotes: 4
Reputation: 78832
You can just reshape your StateTemp
to get what you want (in this example using dplyr
& tidyr
):
StateTemp <- read.table(text=" Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
AL 44.29 48.04 55.47 61.99 69.89 76.75 79.87 79.04 73.88 63.08 54.10 46.85
AZ 42.27 46.24 51.03 57.63 66.01 75.51 80.19 78.50 72.52 61.61 49.64 42.51
AR 38.48 43.76 51.96 60.36 68.62 76.40 80.57 79.26 72.26 61.47 50.32 41.59
CA 45.14 48.51 51.76 56.50 63.11 70.18 75.32 74.62 69.97 61.56 51.17 44.98
CO 23.71 28.34 35.57 43.06 52.50 62.15 67.60 65.75 57.72 46.64 33.51 25.20
CT 25.96 28.43 36.94 47.07 57.77 66.29 71.52 69.77 61.68 50.60 41.43 31.13", header=TRUE)
library(tidyr)
library(dplyr)
StateTemp %>%
add_rownames(var="State") %>%
gather(Month, Temp, -State)
## Source: local data frame [72 x 3]
##
## State Month Temp
## 1 AL Jan 44.29
## 2 AZ Jan 42.27
## 3 AR Jan 38.48
## 4 CA Jan 45.14
## 5 CO Jan 23.71
## 6 CT Jan 25.96
## 7 AL Feb 48.04
## 8 AZ Feb 46.24
## 9 AR Feb 43.76
## 10 CA Feb 48.51
## .. ... ... ...
Upvotes: 1