根据特定列 R 中的值将列值乘以另一个值
Multiplying column value by another value depending on value in certain column R
在以下数据集中,我想将 Size
列中的值乘以 Month1
、Month2
或 Month3
列中的值,具体取决于我们拥有的数字在 Month
列中。因此,如果在某行中 Month
值为 2,我想将 Size
列中的值乘以 Month2
列中的值并将结果保存在新列 NewSize
.非常感谢您的提前帮助!
Orig = c("A","B","A","A","B","A","A","B","A")
Dest = c("B","A","C","B","A","C","B","A","C")
Month = c(1,1,1,2,2,2,3,3,3)
Size = c(30,20,10,10,20,20,30,50,20)
Month1 = c(1,0.2,0,1,0.2,0,1,0.2,0)
Month2 = c(0.6,1,0,0.6,1,0,0.6,1,0)
Month3 = c(0,1,0.6,0,1,0.6,0,1,0.6)
df <- data.frame(Orig,Dest,Month,Size,Month1,Month2,Month3)
df
Orig Dest Month Size Month1 Month2 Month3
1 A B 1 30 1.0 0.6 0.0
2 B A 1 20 0.2 1.0 1.0
3 A C 1 10 0.0 0.0 0.6
4 A B 2 10 1.0 0.6 0.0
5 B A 2 20 0.2 1.0 1.0
6 A C 2 20 0.0 0.0 0.6
7 A B 3 30 1.0 0.6 0.0
8 B A 3 50 0.2 1.0 1.0
9 A C 3 20 0.0 0.0 0.6
这是使用 ifelse
的另一种选择
> transform(df, NewSize=ifelse(Month==1, Size*Month1,
ifelse(Month==2, Size*Month2, Size*Month3)))
Orig Dest Month Size Month1 Month2 Month3 NewSize
1 A B 1 30 1.0 0.6 0.0 30
2 B A 1 20 0.2 1.0 1.0 4
3 A C 1 10 0.0 0.0 0.6 0
4 A B 2 10 1.0 0.6 0.0 6
5 B A 2 20 0.2 1.0 1.0 20
6 A C 2 20 0.0 0.0 0.6 0
7 A B 3 30 1.0 0.6 0.0 0
8 B A 3 50 0.2 1.0 1.0 50
9 A C 3 20 0.0 0.0 0.6 12
以下是我使用 data.table
处理此问题的方法。
require(data.table)
setkey(setDT(df),
Month)[.(mon = 1:3), ## i
NewSize := Size * get(paste0("Month", mon)), ## j
by=.EACHI] ## by
setDT
通过引用将 df
从 data.frame 转换为 data.table .
setkey
按指定的列 Month
对 data.table 重新排序,按升序排列,并将该列标记为 key 列,我们将对其执行连接。
我们对先前集合中的键列集合执行连接,其值为 1:3
。这也可以解释为 subset 操作,从键列 Month
.
中提取所有匹配 1,2 and 3
的行
因此,对于 1:3
的每个值,我们计算 i
中的匹配行。在那些匹配的行上,我们通过为那些匹配的行提取 Size
和 MonthX
并将它们相乘来计算 NewSize
。我们使用get()
来实现提取右MonthX
列。
by=.EACHI
顾名思义,对每个i
执行j
中的表达式。例如,i=1
匹配(或连接)到 df
的行 1:3。对于这些行,j 表达式提取 Size = 30,20,10
和 Month1 = 1.0, 0.2, 0.0
,并将其计算为 return 30, 4, 0
。然后 i=2
等等..
即使您正在寻找 dplyr
唯一的答案,希望这对您有所帮助。
您可以使用 apply
:
apply(df, 1, function(u) as.numeric(u[paste0('Month', u['Month'])])*as.numeric(u['Size']))
#[1] 30 4 0 6 20 0 0 50 12
或矢量化解决方案:
bool = matrix(rep(df$Month, each=3)==rep(1:3, nrow(df)), byrow=T, ncol=3)
df[c('Month1', 'Month2', 'Month3')][bool] * df$Size
#[1] 30 4 0 6 20 0 0 50 12
在 base R 中,完全矢量化:
df$Size*df[,5:7][cbind(1:nrow(df),df$Month)]
在以下数据集中,我想将 Size
列中的值乘以 Month1
、Month2
或 Month3
列中的值,具体取决于我们拥有的数字在 Month
列中。因此,如果在某行中 Month
值为 2,我想将 Size
列中的值乘以 Month2
列中的值并将结果保存在新列 NewSize
.非常感谢您的提前帮助!
Orig = c("A","B","A","A","B","A","A","B","A")
Dest = c("B","A","C","B","A","C","B","A","C")
Month = c(1,1,1,2,2,2,3,3,3)
Size = c(30,20,10,10,20,20,30,50,20)
Month1 = c(1,0.2,0,1,0.2,0,1,0.2,0)
Month2 = c(0.6,1,0,0.6,1,0,0.6,1,0)
Month3 = c(0,1,0.6,0,1,0.6,0,1,0.6)
df <- data.frame(Orig,Dest,Month,Size,Month1,Month2,Month3)
df
Orig Dest Month Size Month1 Month2 Month3
1 A B 1 30 1.0 0.6 0.0
2 B A 1 20 0.2 1.0 1.0
3 A C 1 10 0.0 0.0 0.6
4 A B 2 10 1.0 0.6 0.0
5 B A 2 20 0.2 1.0 1.0
6 A C 2 20 0.0 0.0 0.6
7 A B 3 30 1.0 0.6 0.0
8 B A 3 50 0.2 1.0 1.0
9 A C 3 20 0.0 0.0 0.6
这是使用 ifelse
> transform(df, NewSize=ifelse(Month==1, Size*Month1,
ifelse(Month==2, Size*Month2, Size*Month3)))
Orig Dest Month Size Month1 Month2 Month3 NewSize
1 A B 1 30 1.0 0.6 0.0 30
2 B A 1 20 0.2 1.0 1.0 4
3 A C 1 10 0.0 0.0 0.6 0
4 A B 2 10 1.0 0.6 0.0 6
5 B A 2 20 0.2 1.0 1.0 20
6 A C 2 20 0.0 0.0 0.6 0
7 A B 3 30 1.0 0.6 0.0 0
8 B A 3 50 0.2 1.0 1.0 50
9 A C 3 20 0.0 0.0 0.6 12
以下是我使用 data.table
处理此问题的方法。
require(data.table)
setkey(setDT(df),
Month)[.(mon = 1:3), ## i
NewSize := Size * get(paste0("Month", mon)), ## j
by=.EACHI] ## by
setDT
通过引用将df
从 data.frame 转换为 data.table .setkey
按指定的列Month
对 data.table 重新排序,按升序排列,并将该列标记为 key 列,我们将对其执行连接。我们对先前集合中的键列集合执行连接,其值为
1:3
。这也可以解释为 subset 操作,从键列Month
. 中提取所有匹配 因此,对于
1:3
的每个值,我们计算i
中的匹配行。在那些匹配的行上,我们通过为那些匹配的行提取Size
和MonthX
并将它们相乘来计算NewSize
。我们使用get()
来实现提取右MonthX
列。by=.EACHI
顾名思义,对每个i
执行j
中的表达式。例如,i=1
匹配(或连接)到df
的行 1:3。对于这些行,j 表达式提取Size = 30,20,10
和Month1 = 1.0, 0.2, 0.0
,并将其计算为 return30, 4, 0
。然后i=2
等等..
1,2 and 3
的行
即使您正在寻找 dplyr
唯一的答案,希望这对您有所帮助。
您可以使用 apply
:
apply(df, 1, function(u) as.numeric(u[paste0('Month', u['Month'])])*as.numeric(u['Size']))
#[1] 30 4 0 6 20 0 0 50 12
或矢量化解决方案:
bool = matrix(rep(df$Month, each=3)==rep(1:3, nrow(df)), byrow=T, ncol=3)
df[c('Month1', 'Month2', 'Month3')][bool] * df$Size
#[1] 30 4 0 6 20 0 0 50 12
在 base R 中,完全矢量化:
df$Size*df[,5:7][cbind(1:nrow(df),df$Month)]