通过在 R 中传递 2 个变量来提取数据帧的单个值
Extract a single value of dataframe by passing 2 variables in R
我有一个查找 table,我想通过传递我的数据框的两个变量来提取此查找的单个值 table。一个变量匹配行 (P=P1),第二个变量匹配查找的列 table(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"))
我只想在我的数据框中添加相应的 lookup_table 值。
我导出了以下函数,但它不起作用。
get_from_lookup_table <- function(P,var1){
lookup_table[P == P,..var1]
}
当我执行该函数并尝试将新列添加到我的数据框中时,所有值都显示为多列。
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 <multi-column>
2: 6 C <multi-column>
3: 8 A <multi-column>
4: 2 B <multi-column>
5: 6 C <multi-column>
6: 8 A <multi-column>
7: 4 A <multi-column>
8: 2 B <multi-column>
9: 6 C <multi-column>
10: 4 A <multi-column>
看起来很简单,但我的数据框有超过 50000 行。
我们可以在 base R
中使用矢量化方法。将 data.table
转换为 data.frame
,通过 match
使用 lookup_table 'P' 列和名称对数据集的列进行 row/col
umn 索引lookup_table 创建一个 matrix
或 row/column 索引。用它来提取相应的值
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)))]
-输出
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
或者另一种选择是通过遍历序列
进行连接和 get
列的值
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
但是,这绝对没有效率:
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
我有一个查找 table,我想通过传递我的数据框的两个变量来提取此查找的单个值 table。一个变量匹配行 (P=P1),第二个变量匹配查找的列 table(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"))
我只想在我的数据框中添加相应的 lookup_table 值。
我导出了以下函数,但它不起作用。
get_from_lookup_table <- function(P,var1){
lookup_table[P == P,..var1]
}
当我执行该函数并尝试将新列添加到我的数据框中时,所有值都显示为多列。
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 <multi-column>
2: 6 C <multi-column>
3: 8 A <multi-column>
4: 2 B <multi-column>
5: 6 C <multi-column>
6: 8 A <multi-column>
7: 4 A <multi-column>
8: 2 B <multi-column>
9: 6 C <multi-column>
10: 4 A <multi-column>
看起来很简单,但我的数据框有超过 50000 行。
我们可以在 base R
中使用矢量化方法。将 data.table
转换为 data.frame
,通过 match
使用 lookup_table 'P' 列和名称对数据集的列进行 row/col
umn 索引lookup_table 创建一个 matrix
或 row/column 索引。用它来提取相应的值
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)))]
-输出
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
或者另一种选择是通过遍历序列
进行连接和get
列的值
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
但是,这绝对没有效率:
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