# Create fake data frame
score <- rep(seq(1:3), 2)
id <- rep(c(2014, 2015), each = 3)
var_if_1 <- rep(c(0.1, 0.8), each = 3)
var_if_2 <- rep(c(0.9, 0.7), each = 3)
var_if_3 <- rep(c(0.6, 0.2), each = 3)
data.frame(score, id, var_if_1, var_if_2, var_if_3)
更具体地说,每一行由数据框中的两个向量唯一定义(例如得分和id),并且有许多以字符串开头的附加列(例如&#34; var_if _&#34;)和结束用不同的数字(例如1,2,3)。此外,对于给定的分数值(即对于具有给定分数的任何行),附加变量的值不会变化。
# Desired output data frame
score <- rep(seq(1:3), 2)
id <- rep(c(2014, 2015), each = 3)
var <- c(0.1, 0.9, 0.6, 0.8, 0.7, 0.2)
data.frame(score, id, var)
更具体地,附加变量(var_if_#)被移除并聚合成单个新变量(例如var),该变量基于得分值取得一个附加变量列的值。例如,如果得分== 2,则var == var_if_2。
下面举例说明了任意行排序。
score <- rep(seq(1:3), 2)
id <- rep(c(2014, 2015), each = 3)
var_if_1 <- rep(c(0.1, 0.8), each = 3)
var_if_2 <- rep(c(0.9, 0.7), each = 3)
var_if_3 <- rep(c(0.6, 0.2), each = 3)
foo <- data.frame(score, id, var_if_1, var_if_2, var_if_3)
foo[sample(1:nrow(foo)), ] # arbitrary row order
我也知道我可以使用ifelse()但这会变成 很多可能的分数值很繁琐(除非有循环 可以减少乏味的方法。
答案 0 :(得分:4)
使用矩阵索引,避免慢速循环或apply
逻辑:
cbind(dat[1:2], var=dat[3:5][cbind(seq_len(nrow(dat)), dat$score)])
# score id var
#1 1 2014 0.1
#2 2 2014 0.9
#3 3 2014 0.6
#4 1 2015 0.8
#5 2 2015 0.7
#6 3 2015 0.2
如果您专门匹配var_if_1
等名称模式,请使用match
获取要提取的列:
dat[cbind( seq_len(nrow(dat)), match(paste0("var_if_", dat$score), names(dat)))]
答案 1 :(得分:2)
您可以使用函数apply
,它将迭代数据框的每一行。如果列的特定顺序如下所示:
var <- apply(my_data_frame, 1, function(x) { x[x["score"] + 2] })
如果您想使用列的名称而不是其位置,可以将x["score"] + 2]
替换为x[paste0("var_if_",x["score"])]