Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

reshape adding two columns to data.frame

Tags:

r

reshape

I have a data.frame that looks like this

    timestamp value.x station value.y   parameter.x   value parameter.y
1   1/1/2010  0.6     abc     188,000   AREA PLANTED    22  PROGRESS
2   1/1/2010  0.6     abc     156.3     YIELD           NA  NA
3   1/1/2010  -10     def     188,000   AREA PLANTED    22  PROGRESS
4   1/1/2010  -10     def     156.3     YIELD           NA  NA

And I want to use reshape to make it look like this:

    timestamp   value.x station AREA PLANTED    YIELD   PROGRESS
1   1/1/2010    0.6     abc     188,000         156.3   22       
3   1/1/2010    -10     def     188,000         156.3   22

I tried

reshape(data = b, varying = list(c('value.y', 'parameter.x', 'value', 'parameter.y')), 
        v.names = c('AREA PLANTED', 'YIELD', 'PROGRESS'), 
        timevar = row.names(b), 
        times = b$timestamp, direction = 'wide', idvar = b$station)

But it says

Error in [.data.frame(data, , idvar) : undefined columns selected

I tried changing it a bit, but no matter what I do it keeps throwing this error.

like image 808
Rafael Avatar asked Jul 31 '26 00:07

Rafael


2 Answers

This uses reshape2. I don't think it is possible to cast the dataframe in a single step. Note that it appears that the input is the result of some other join operation (because some of the names have .x and . suffixes). I guess that join could be improved to avoid this complication

df <- read.table(header=TRUE, stringsAsFactors = FALSE, text = 
"timestamp value.x station value.y   parameter.x   value parameter.y
1/1/2010  0.6     abc     188,000   AREAPLANTED    22  PROGRESS
1/1/2010  0.6     abc     156.3     YIELD           NA  NA
1/1/2010  -10     def     188,000   AREAPLANTED    22  PROGRESS
1/1/2010  -10     def     156.3     YIELD           NA  NA
")

library(reshape2)

# extract the last two columns into a variable/value and make unique
df1 <- unique(df[!is.na(df$value),c("timestamp", "value.x", "station", "parameter.y", "value")])
names(df1) <- c("timestamp", "value.x", "station", "variable", "value")

# extract columns 4,5 into a variable value
df2 <- df[,c("timestamp", "value.x", "station", "parameter.x", "value.y")]
names(df2) <- c("timestamp", "value.x", "station", "variable", "value")

# cast
dcast(rbind(df1, df2), timestamp + value.x + station ~ variable, value.var = "value")

#   timestamp value.x station AREAPLANTED PROGRESS YIELD
# 1  1/1/2010   -10.0     def     188,000       22 156.3
# 2  1/1/2010     0.6     abc     188,000       22 156.3
like image 118
Andrew Lavers Avatar answered Aug 01 '26 14:08

Andrew Lavers


Still in base R, consider a merge between two reshape dataframes as you require. Your current setup uses arguments intended for the wide to long reshape and not vice versa as you need.

mdf <- merge(
  reshape(b, timevar="parameter.x",
        v.names = c("value.y"),
        idvar = c("timestamp", "value.x", "station"),
        direction = "wide",
        drop = c("value", "parameter.y")),

  reshape(b[!is.na(b$value),], timevar="parameter.y",
        v.names = c("value"),
        idvar = c("timestamp", "value.x", "station"),
        direction = "wide",
        drop = c("value.y", "parameter.x")),
  by=c("timestamp", "value.x", "station")
)

names(mdf) <- gsub("(value\\.y\\.|value\\.)", "", names(mdf))

mdf    
#   timestamp     x station AREA PLANTED YIELD PROGRESS
# 1  1/1/2010 -10.0     def      188,000 156.3       22
# 2  1/1/2010   0.6     abc      188,000 156.3       22
like image 41
Parfait Avatar answered Aug 01 '26 14:08

Parfait



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!