如何使用查找 table 和 R 中的公式创建计算列?
How to create a calculated column using a lookup table and a formula in R?
我有一个如下所示的数据框:
V1 V2 V3
3 4 3
2 4 3
4 4 3
4 4 4
1 4 2
4 2 4
4 4 1
4 4 2
3 4 1
4 4 4
4 4 2
4 4 2
2 1 2
3 2 3
3 4 3
3 4 2
4 4 2
4 4 4
2 3 3
3 4 1
我也有这样的查找 table:
V_id coeff weight
V1 0.82 4.77
V2 0.75 4.77
V3 0.67 4.77
我想在查找中使用这些值 table 使用
在 DF1 中创建一个新的计算列
(V1*coeff+V2*coeff+V3*coeff)/weight
最终数据框应如下所示。
V1 V2 V3 new_column
3 4 3 1.566037736
2 4 3 1.394129979
4 4 3 1.737945493
4 4 4 1.878406709
1 4 2 1.081761006
4 2 4 1.5639413
4 4 1 1.457023061
4 4 2 1.597484277
3 4 1 1.285115304
4 4 4 1.878406709
4 4 2 1.597484277
4 4 2 1.597484277
2 1 2 0.78197065
3 2 3 1.251572327
3 4 3 1.566037736
3 4 2 1.42557652
4 4 2 1.597484277
4 4 4 1.878406709
2 3 3 1.236897275
3 4 1 1.285115304
我必须为具有 1125 列的数据框执行此操作。
我们可以先把第一条数据转成长格式,然后按行号分组,得到计算出来的列
library(dplyr)
library(tidyr)
df1 %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = -rn, names_to = "V_id") %>%
left_join(df2) %>%
group_by(rn) %>%
summarise(new_column = sum(coeff *value)/weight[1]) %>%
select(new_column) %>%
bind_cols(df1, .)
# A tibble: 20 x 4
# V1 V2 V3 new_column
# <int> <int> <int> <dbl>
# 1 3 4 3 1.57
# 2 2 4 3 1.39
# 3 4 4 3 1.74
# 4 4 4 4 1.88
# 5 1 4 2 1.08
# 6 4 2 4 1.56
# 7 4 4 1 1.46
# 8 4 4 2 1.60
# 9 3 4 1 1.29
#10 4 4 4 1.88
#11 4 4 2 1.60
#12 4 4 2 1.60
#13 2 1 2 0.782
#14 3 2 3 1.25
#15 3 4 3 1.57
#16 3 4 2 1.43
#17 4 4 2 1.60
#18 4 4 4 1.88
#19 2 3 3 1.24
#20 3 4 1 1.29
在base R
中,我们也可以做到
df1$new_column <- c(tcrossprod(df2$coeff, as.matrix(df1)))/df2$weight[1]
数据
df1 <- structure(list(V1 = c(3L, 2L, 4L, 4L, 1L, 4L, 4L, 4L, 3L, 4L,
4L, 4L, 2L, 3L, 3L, 3L, 4L, 4L, 2L, 3L), V2 = c(4L, 4L, 4L, 4L,
4L, 2L, 4L, 4L, 4L, 4L, 4L, 4L, 1L, 2L, 4L, 4L, 4L, 4L, 3L, 4L
), V3 = c(3L, 3L, 3L, 4L, 2L, 4L, 1L, 2L, 1L, 4L, 2L, 2L, 2L,
3L, 3L, 2L, 2L, 4L, 3L, 1L)), class = "data.frame", row.names = c(NA,
-20L))
df2 <- structure(list(V_id = c("V1", "V2", "V3"), coeff = c(0.82, 0.75,
0.67), weight = c(4.77, 4.77, 4.77)), class = "data.frame", row.names = c(NA,
-3L))
编辑更新问题的更新答案(数据框有 1,125 列):
df1_V <- as.matrix(df1) # or select the "V" columns using df1[, 1:1125]
df1$new_column <- df1_V %*% df2$coef / df2$weight[1]
这是一个通用的解决方案,只要 df1 的列以相同的方式排列(跨数据框的列),它就适用于任意数量的列由于 coef 值在 df2、 和 中按行排序,因此 df1[=32= 中的列数]等于df2中的行数,即ncol(df1_V) = nrow(df2)
。
回答(原问题):
library(dplyr)
df %>%
mutate(new_column = (V1*0.82 + V2*0.75 + V3*0.67) / 4.77)
V1 V2 V3 new_column
1 3 4 3 1.5660377
2 2 4 3 1.3941300
3 4 4 3 1.7379455
4 4 4 4 1.8784067
5 1 4 2 1.0817610
6 4 2 4 1.5639413
...
选择:
df1$new_column <- as.matrix(df1) %*% c(0.82, 0.75, 0.67) / 4.77
我有一个如下所示的数据框:
V1 V2 V3
3 4 3
2 4 3
4 4 3
4 4 4
1 4 2
4 2 4
4 4 1
4 4 2
3 4 1
4 4 4
4 4 2
4 4 2
2 1 2
3 2 3
3 4 3
3 4 2
4 4 2
4 4 4
2 3 3
3 4 1
我也有这样的查找 table:
V_id coeff weight
V1 0.82 4.77
V2 0.75 4.77
V3 0.67 4.77
我想在查找中使用这些值 table 使用
在 DF1 中创建一个新的计算列(V1*coeff+V2*coeff+V3*coeff)/weight
最终数据框应如下所示。
V1 V2 V3 new_column
3 4 3 1.566037736
2 4 3 1.394129979
4 4 3 1.737945493
4 4 4 1.878406709
1 4 2 1.081761006
4 2 4 1.5639413
4 4 1 1.457023061
4 4 2 1.597484277
3 4 1 1.285115304
4 4 4 1.878406709
4 4 2 1.597484277
4 4 2 1.597484277
2 1 2 0.78197065
3 2 3 1.251572327
3 4 3 1.566037736
3 4 2 1.42557652
4 4 2 1.597484277
4 4 4 1.878406709
2 3 3 1.236897275
3 4 1 1.285115304
我必须为具有 1125 列的数据框执行此操作。
我们可以先把第一条数据转成长格式,然后按行号分组,得到计算出来的列
library(dplyr)
library(tidyr)
df1 %>%
mutate(rn = row_number()) %>%
pivot_longer(cols = -rn, names_to = "V_id") %>%
left_join(df2) %>%
group_by(rn) %>%
summarise(new_column = sum(coeff *value)/weight[1]) %>%
select(new_column) %>%
bind_cols(df1, .)
# A tibble: 20 x 4
# V1 V2 V3 new_column
# <int> <int> <int> <dbl>
# 1 3 4 3 1.57
# 2 2 4 3 1.39
# 3 4 4 3 1.74
# 4 4 4 4 1.88
# 5 1 4 2 1.08
# 6 4 2 4 1.56
# 7 4 4 1 1.46
# 8 4 4 2 1.60
# 9 3 4 1 1.29
#10 4 4 4 1.88
#11 4 4 2 1.60
#12 4 4 2 1.60
#13 2 1 2 0.782
#14 3 2 3 1.25
#15 3 4 3 1.57
#16 3 4 2 1.43
#17 4 4 2 1.60
#18 4 4 4 1.88
#19 2 3 3 1.24
#20 3 4 1 1.29
在base R
中,我们也可以做到
df1$new_column <- c(tcrossprod(df2$coeff, as.matrix(df1)))/df2$weight[1]
数据
df1 <- structure(list(V1 = c(3L, 2L, 4L, 4L, 1L, 4L, 4L, 4L, 3L, 4L,
4L, 4L, 2L, 3L, 3L, 3L, 4L, 4L, 2L, 3L), V2 = c(4L, 4L, 4L, 4L,
4L, 2L, 4L, 4L, 4L, 4L, 4L, 4L, 1L, 2L, 4L, 4L, 4L, 4L, 3L, 4L
), V3 = c(3L, 3L, 3L, 4L, 2L, 4L, 1L, 2L, 1L, 4L, 2L, 2L, 2L,
3L, 3L, 2L, 2L, 4L, 3L, 1L)), class = "data.frame", row.names = c(NA,
-20L))
df2 <- structure(list(V_id = c("V1", "V2", "V3"), coeff = c(0.82, 0.75,
0.67), weight = c(4.77, 4.77, 4.77)), class = "data.frame", row.names = c(NA,
-3L))
编辑更新问题的更新答案(数据框有 1,125 列):
df1_V <- as.matrix(df1) # or select the "V" columns using df1[, 1:1125]
df1$new_column <- df1_V %*% df2$coef / df2$weight[1]
这是一个通用的解决方案,只要 df1 的列以相同的方式排列(跨数据框的列),它就适用于任意数量的列由于 coef 值在 df2、 和 中按行排序,因此 df1[=32= 中的列数]等于df2中的行数,即ncol(df1_V) = nrow(df2)
。
回答(原问题):
library(dplyr)
df %>%
mutate(new_column = (V1*0.82 + V2*0.75 + V3*0.67) / 4.77)
V1 V2 V3 new_column
1 3 4 3 1.5660377
2 2 4 3 1.3941300
3 4 4 3 1.7379455
4 4 4 4 1.8784067
5 1 4 2 1.0817610
6 4 2 4 1.5639413
...
选择:
df1$new_column <- as.matrix(df1) %*% c(0.82, 0.75, 0.67) / 4.77