Reputation: 664
I'm a beginner in R, I have the following data, where table is like this:
dt
fct X Y Z fct1 Q
1: a 2 1 a:a a a:a:2
2: b 4 2 b:b b b:b:4
3: c 3 1 c:c c c:c:3
4: d 2 2 d:d d d:d:2
5: c 5 1 c:c c c:c:5
6: d 4 2 d:d d d:d:4
7: a 7 1 a:a a a:a:7
8: b 2 2 b:b b b:b:2
9: c 9 1 c:c c c:c:9
10: a 1 2 a:a a a:a:1
11: b 4 1 b:b b b:b:4
12: c 2 2 c:c c c:c:2
13: b 5 1 b:b b b:b:5
14: c 4 2 c:c c c:c:4
15: d 2 1 d:d d d:d:2`
and, have a List like this:
flist
$a
[1] "X + Y"
$b
[1] "X - Y"
$c
[1] "X * Y"
$d
[1] "paste0(Z,':',fct)"
Since flist
has an entry for a
, whenever an entry a
in fct
column is seen, then the corresponding formula from the list needs to be executed, using the values of Y
and Z
column, and applied to Column XY
.
I tried solution like this:
within(dt2, XY <- eval(parse(text=flist['a'])))
, which works with the clearly seen constraint, which is, it can only be applied with the formula for a
.
However, this: within(dt2, XY <- eval(parse(text=flist[fct])))
doesn't work.
Even this: within(dt2, XY <- eval(parse(text=eval(parse(text=flist[fct]))))))
doesn't work.
Use case is that, looking into fct
Column, its variable should be used to look up the formula in flist
, and then applied with the Data in X
and Y
and applied to XY
.
I kindly look forward for help.
Upvotes: 2
Views: 51
Reputation: 886948
We can use the data.table
methods by specifying the logical condition in 'i' (assuming that 'fct' is character
class and assign (:=
) the evaluated string from the list
element (flist$a
) to create the new column 'XY'
dt[fct == names(flist), XY := eval(parse(text=flist$a))]
dt
# fct X Y Z fct1 Q XY
# 1: a 2 1 a:a a a:a:2 3
# 2: b 4 2 b:b b b:b:4 NA
# 3: c 3 1 c:c c c:c:3 NA
# 4: d 2 2 d:d d d:d:2 NA
# 5: c 5 1 c:c c c:c:5 NA
# 6: d 4 2 d:d d d:d:4 NA
# 7: a 7 1 a:a a a:a:7 8
# 8: b 2 2 b:b b b:b:2 NA
# 9: c 9 1 c:c c c:c:9 NA
#10: a 1 2 a:a a a:a:1 3
#11: b 4 1 b:b b b:b:4 NA
#12: c 2 2 c:c c c:c:2 NA
#13: b 5 1 b:b b b:b:5 NA
#14: c 4 2 c:c c c:c:4 NA
#15: d 2 1 d:d d d:d:2 NA
If there are multiple elements in 'flist'
for(j in seq_along(flist)){
dt[fct == names(flist)[j], XY := eval(parse(text= flist[[j]]))][]
}
dt
# fct X Y Z fct1 Q XY
# 1: a 2 1 a:a a a:a:2 3
# 2: b 4 2 b:b b b:b:4 2
# 3: c 3 1 c:c c c:c:3 3
# 4: d 2 2 d:d d d:d:2 NA
# 5: c 5 1 c:c c c:c:5 5
# 6: d 4 2 d:d d d:d:4 NA
# 7: a 7 1 a:a a a:a:7 8
# 8: b 2 2 b:b b b:b:2 0
# 9: c 9 1 c:c c c:c:9 9
#10: a 1 2 a:a a a:a:1 3
#11: b 4 1 b:b b b:b:4 3
#12: c 2 2 c:c c c:c:2 4
#13: b 5 1 b:b b b:b:5 4
#14: c 4 2 c:c c c:c:4 8
#15: d 2 1 d:d d d:d:2 NA
flist <- list(a= "X + Y")
#updated flist
flist <- list(a = "X + Y", b = "X - Y", c = "X * Y")
Upvotes: 2