编写间接引用变量以绕过硬编码的R代码是否效率低下?
假设我有下面的数据框:编写间接引用变量以绕过硬编码的R代码是否效率低下?,r,R,假设我有下面的数据框: x <- data.frame(id= c("a", "b", "c", "d", "e") , term= c(179, 192, 189, 182, 179) , f17= c(1, 2, 3, 4, 5) , s18= c(6, 7, 8, 9, 10) , f18 = c(11, 12, 13, 14, 15)
x <- data.frame(id= c("a", "b", "c", "d", "e")
, term= c(179, 192, 189, 182, 179)
, f17= c(1, 2, 3, 4, 5)
, s18= c(6, 7, 8, 9, 10)
, f18 = c(11, 12, 13, 14, 15)
, s19 = c(16, 17, 18, 19, 20))
上面代码的想法是,当我获得新数据时,我只需要更新xterm和xVars的定义。或者,我甚至可以根据x中变量和x中变量的唯一值列表动态创建这些变量
我很想从更有经验的R用户那里得到反馈,如果这是解决R中此类迭代问题的最佳方法?关于如何更好地利用R做这类事情,您可以分享哪些资源?您可以使用
match
xTerms <- c(179, 182, 189, 192)
xVars <- c("f17", "s18", "f18", "s19")
x$startVal <- sapply(1:nrow(x), function(i) x[i, xVars[match(x$term[i], xTerms)]])
x
id term f17 s18 f18 s19 startVal
1 a 179 1 6 11 16 1
2 b 192 2 7 12 17 17
3 c 189 3 8 13 18 13
4 d 182 4 9 14 19 9
5 e 179 5 10 15 20 5
xTerms一个选项是使用行/列
索引
x$startVal <- x[3:6][cbind(seq_len(nrow(x)),
match(xVars[match(x$term, xTerms)], names(x)[3:6]))]
x
# id term f17 s18 f18 s19 startVal
#1 a 179 1 6 11 16 1
#2 b 192 2 7 12 17 17
#3 c 189 3 8 13 18 13
#4 d 182 4 9 14 19 9
#5 e 179 5 10 15 20 5
x$startVal如果将xTerms
和xVars
放在查找表lkp
中,您可以使用melt
将数据转换为长格式,并使用lkp
加入以获得起始VAL。然后您可以返回到x
,将其添加为列
library(data.table)
setDT(x)
lkp <- data.table(Terms = xTerms, Vars = xVars)
startvals <- melt(x, c('id', 'term'))[lkp, on = .(term == Terms, variable == Vars)]
x[startvals, on = .(id, term), startVal := value]
x
# id term f17 s18 f18 s19 startVal
# 1: a 179 1 6 11 16 1
# 2: b 192 2 7 12 17 17
# 3: c 189 3 8 13 18 13
# 4: d 182 4 9 14 19 9
# 5: e 179 5 10 15 20 5
库(data.table)
setDT(x)
lkp我认为更好的选择是行.列索引x[cbind(match(xTerms,x$term),match(xVars,names(x))]
!非常感谢你!你使用match的方式给了我很多思考!我以前遇到过函数和apply家族的问题,但我会继续努力!非常感谢。我一直对使用cbind持谨慎态度,因为它基本上是将两列合并在一起,而实际上没有基于一个或多个id变量进行合并,这对我来说很危险,但在这种情况下,我可以看出它是多么强大!我必须更多地使用它。@bericbind
的结果是一个矩阵,与for
loopah相比应该非常快,这在效率方面非常有用!非常感谢。非常感谢。我一直在思考的是,我用于df的结构是否真的是一个好的结构,或者我是否真的应该拥有长格式的数据,而您的回答提醒我要对这个问题进行更多思考。另外,我不熟悉用于连接数据的语法(我一直在使用merge函数),所以我学到了另一个新东西!非常感谢。是的,这种语法是特定于data.table包的。在这个问题上,有一些很好的解释它是如何对应于左/右/内的
x$startVal <- x[3:6][cbind(seq_len(nrow(x)),
match(xVars[match(x$term, xTerms)], names(x)[3:6]))]
x
# id term f17 s18 f18 s19 startVal
#1 a 179 1 6 11 16 1
#2 b 192 2 7 12 17 17
#3 c 189 3 8 13 18 13
#4 d 182 4 9 14 19 9
#5 e 179 5 10 15 20 5
library(data.table)
setDT(x)
lkp <- data.table(Terms = xTerms, Vars = xVars)
startvals <- melt(x, c('id', 'term'))[lkp, on = .(term == Terms, variable == Vars)]
x[startvals, on = .(id, term), startVal := value]
x
# id term f17 s18 f18 s19 startVal
# 1: a 179 1 6 11 16 1
# 2: b 192 2 7 12 17 17
# 3: c 189 3 8 13 18 13
# 4: d 182 4 9 14 19 9
# 5: e 179 5 10 15 20 5