假设我有以下数据框:
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))
在此数据框中,我想创建一个变量,该变量记录给定术语的相应列中每个id的值(f17对应术语179,s18对应术语182,f18对应术语189,f19对应至第192期)。
很显然,这可以通过一系列ifelse语句来轻松完成,但是每隔几个月我就会获得新的数据条款,并且我不想每次获得更多数据时都需要手动重新编码。另外,我发现这种带有大量嵌套ifelse语句的编码非常难以阅读。
我对R还是比较陌生,但是我是一个非常有经验的SAS和SAS宏程序员,所以我知道在SAS中,我想要做的事情可以很容易地通过几个数组和一个数据步骤中的do循环来完成。 ,这实际上是我试图在R中重新创建的东西。我最终要做的事情如下。
注意:我意识到下面的内容与一系列嵌套的ifelse语句不同,而是一系列的ifelse语句,以便覆盖相同的变量,但这确实为我提供了解决方案需要,并考虑我数据中的所有情况。
xTerms <- c(179, 182, 189, 192)
xVars <- c("f17", "s18", "f18", "s19")
x$startVal <- NA
for(i in 1:length(xTerms)){
x$startVal <- ifelse(x$term == xTerms[i], x[[xVars[i]]], x$startVal)
}
我应该添加,这是期望的结果:
> 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和xVars的定义。或者,我什至可以根据x中术语变量和x中变量的值的唯一列表动态创建变量。
如果这是解决R中这类迭代问题的最佳方法,我很想从更多有经验的R用户那里获得反馈?您是否可以共享资源,以更好地利用R来进行这类事情?
答案 0 :(得分:2)
可以使用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
答案 1 :(得分:2)
如果您将xTerms
和xVars
放在查找表lkp
中,则可以使用melt
将数据转换为长格式,并与lkp
合并以获得起始值。然后,您可以重新加入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
答案 2 :(得分:1)
一种选择是使用row/column
索引
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