使用行中带有变量名称的数据对列进行重新编码
Recode columns using data with variable names in rows
我有两个数据框:
- 使用列
varName
(变量名称)、key
和 value
查找 table lookup
- 数据框
df
,其列的名称与 varName
中的值完全相同,值对应于 key
(df
中的值是 lookup
的键) .此数据框比查找数据框大得多(例如 1e6 行)。
我想通过为每个变量附加新列来重新编码 df
中的数据,其中 df
中的键被 lookup
数据框中相应的 value
替换.重要的是要注意键是双精度类型。
示例数据:
# 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']
)
我目前的解决方案使用临时重命名变量和 join
来自 plyr
:
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
问题:
- 这样安全吗?如果使用
join
加入 double
将始终正常工作,我找不到任何信息
- 是否有更好的方法可以更安全、更快地完成同样的任务?
你可以试试 data.table
。使用 set.seed(20)
创建 "df" (为了可重复性)。我使用 melt
将 "df" 重塑为 "long",转换为 "data.table"(as.data.table
),而不是 "wide" 格式,设置键列(setkey(..)
),加入"lookup"数据集,用dcast.data.table
转换回"wide"格式,最后加入原始数据集,这样就有新旧列在数据集。这也可以使用没有 reshaping
的 for
循环来完成
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
我有两个数据框:
- 使用列
varName
(变量名称)、key
和value
查找 table - 数据框
df
,其列的名称与varName
中的值完全相同,值对应于key
(df
中的值是lookup
的键) .此数据框比查找数据框大得多(例如 1e6 行)。
lookup
我想通过为每个变量附加新列来重新编码 df
中的数据,其中 df
中的键被 lookup
数据框中相应的 value
替换.重要的是要注意键是双精度类型。
示例数据:
# 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']
)
我目前的解决方案使用临时重命名变量和 join
来自 plyr
:
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
问题:
- 这样安全吗?如果使用
join
加入 - 是否有更好的方法可以更安全、更快地完成同样的任务?
double
将始终正常工作,我找不到任何信息
你可以试试 data.table
。使用 set.seed(20)
创建 "df" (为了可重复性)。我使用 melt
将 "df" 重塑为 "long",转换为 "data.table"(as.data.table
),而不是 "wide" 格式,设置键列(setkey(..)
),加入"lookup"数据集,用dcast.data.table
转换回"wide"格式,最后加入原始数据集,这样就有新旧列在数据集。这也可以使用没有 reshaping
for
循环来完成
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