2015-01-08 31 views
1

我有两个数据帧:重新编码列

  • 查找表lookup用完全按命名的列varName(变量名),key,和value
  • 数据帧df与列varName中的值以及对应于key的值(df中的值是lookup的关键)。该数据帧比查找数据帧大得多(例如1e6行)。

我想通过对于每个变量,其中在df密钥由从lookup数据帧对应value代替追加新列重新编码在df数据。重要的是要注意,键是双重类型的。

的样本数据:

# Generate sample data 
lookup <- data.frame(
    varName = rep(LETTERS[1:3], each = 3), 
    key  = runif(9), 
    value = runif(9) 
) 

df <- expand.grid(
    A = lookup[lookup$varName == 'A', 'key'], 
    B = lookup[lookup$varName == 'B', 'key'], 
    C = lookup[lookup$varName == 'C', 'key'] 
) 

我目前的解决方案使用的临时变量重命名和joinplyr

require(plyr) 

for (varName in unique(lookup$varName)) { 
    tmpLookup <- rename(lookup, replace = c(key = varName)) 
    df[paste0(varName, '_value')] <- join(df[varName], tmpLookup[c(varName, 'value')], 
             by = varName)['value'] 
} 

df 

问题:

  • 是这样安全吗?我无法找到任何信息,如果加入double将始终正确使用join
  • 有没有更好的方式来完成同样更安全和更快?

回答

1

您可以试试data.table。使用set.seed(20)创建“df”(用于重现性)。使用melt将“df”改为“long”,转换为“data.table”(as.data.table),设置关键列(setkey(..)),加入“查找”数据集,将其转换回以dcast.data.table为“宽”格式,最后加入原始数据集,以便在数据集中添加新列和旧列。这可以使用一个for回路也做而不reshaping

library(data.table) 
library(reshape2) 
DT <- as.data.table(melt(as.matrix(df))) 
DT1 <- dcast.data.table(setkey(DT, Var2, 
      value)[lookup], Var1~Var2, value.var='i.value') 
DT2 <- setkey(setDT(df)[,Var1:=1:.N], Var1)[DT1][,Var1:=NULL] 

head(DT2,2) 
#   A   B   C  i.A   i.B  i.C 
#1: 0.8775214 0.5291637 0.09133259 0.3700745 0.001927939 0.4520996 
#2: 0.7685332 0.5291637 0.09133259 0.7155276 0.001927939 0.4520996 
+0

第二行('DT1')失败,错误:'错误setkeyv(X,COLS,冗长=冗长,物理=物理):一些列不在data.table:Var2'中。 –

+0

@TomasGreif我无法使用'data.table_1.9.5'重现错误 – akrun