通过在R中传递2个变量来提取dataframe的单个值

通过在R中传递2个变量来提取dataframe的单个值,r,dataframe,data.table,R,Dataframe,Data.table,我有一个查找表,我想通过传递数据帧的两个变量来提取这个查找表的单个值。一个变量与行(P=P1)匹配,第二个变量与查找表的列(A、B和C)匹配 这是一个我正在努力完成的例子 #lookup table lookup_table <- data.table(P=c(2,4,6,8), A=c(10:13), B=c(20:23), C

我有一个查找表,我想通过传递数据帧的两个变量来提取这个查找表的单个值。一个变量与行(P=P1)匹配,第二个变量与查找表的列(A、B和C)匹配

这是一个我正在努力完成的例子

#lookup table
lookup_table <- data.table(P=c(2,4,6,8),
                           A=c(10:13),
                           B=c(20:23),
                           C=c(30,33))
#my data frame that I want to incorporate the lookup table values
my_data <- data.table(P1=c(4,6,8,2,6,8,4,2,6,4),
                      var1=c("B","C","A","B","C","A","A","B","C","A"))
#查找表

查找表我们可以在
base R
中使用矢量化方法。将
data.table
转换为
data.frame
,使用
row/col
umn索引,方法是
match
将数据集的列与lookup\u table“P”列和lookup\u表的名称进行匹配,以创建
矩阵或行/列索引。使用它来提取相应的值

df1 <- as.data.frame(my_data)
df1$look_up_table_value <- as.data.frame(lookup_table)[cbind(match(df1$P1, 
       lookup_table$P), match(df1$var1, names(lookup_table)))]

或者另一个选项是执行联接,并通过在序列上循环来获取列的值

my_data[, look_up_table_value := my_data[, rn := seq_len(.N)][lookup_table, 
       on = .(P1 = P)][order(rn)][,get(var1), 1:nrow(my_data)]$V1]

mapply
允许使用原始代码:

get_from_lookup_table <- function(P,var1){
  unlist(mapply(function(row,col) lookup_table[P==row,..col],P,var1))
}

get_from_lookup_table(my_data$P1,my_data$var1)
# B  C  A  B  C  A  A  B  C  A 
# 21 30 13 20 30 13 11 20 30 11 


my_data$look_up_table_value <- get_from_lookup_table(my_data$P1,my_data$var1)

my_data

   P1 var1 look_up_table_value
 1:  4    B                  21
 2:  6    C                  30
 3:  8    A                  13
 4:  2    B                  20
 5:  6    C                  30
 6:  8    A                  13
 7:  4    A                  11
 8:  2    B                  20
 9:  6    C                  30
10:  4    A                  11

从查找表中获取\u非常感谢!我试图导出一个函数,以便在将来的工作中使用。但现在也是可能的
df1
   P1 var1 look_up_table_value
1   4    B                  21
2   6    C                  30
3   8    A                  13
4   2    B                  20
5   6    C                  30
6   8    A                  13
7   4    A                  11
8   2    B                  20
9   6    C                  30
10  4    A                  11
my_data[, look_up_table_value := my_data[, rn := seq_len(.N)][lookup_table, 
       on = .(P1 = P)][order(rn)][,get(var1), 1:nrow(my_data)]$V1]
get_from_lookup_table <- function(P,var1){
  unlist(mapply(function(row,col) lookup_table[P==row,..col],P,var1))
}

get_from_lookup_table(my_data$P1,my_data$var1)
# B  C  A  B  C  A  A  B  C  A 
# 21 30 13 20 30 13 11 20 30 11 


my_data$look_up_table_value <- get_from_lookup_table(my_data$P1,my_data$var1)

my_data

   P1 var1 look_up_table_value
 1:  4    B                  21
 2:  6    C                  30
 3:  8    A                  13
 4:  2    B                  20
 5:  6    C                  30
 6:  8    A                  13
 7:  4    A                  11
 8:  2    B                  20
 9:  6    C                  30
10:  4    A                  11
a <- function() {
  df1 <- as.data.frame(my_data)
  df1$look_up_table_value <- as.data.frame(lookup_table)[cbind(match(df1$P1, 
                                                                     lookup_table$P), match(df1$var1, names(lookup_table)))]
  
}
w <- function() {my_data$look_up_table_value <- get_from_lookup_table(my_data$P1,my_data$var1)}

microbenchmark::microbenchmark(a(),w())

Unit: microseconds
 expr     min       lq      mean  median       uq     max neval
  a()   124.8   161.20   308.658   209.0   227.80  5563.0   100
  w() 11300.6 11973.35 13317.676 12340.1 13528.35 26613.7   100