我正试图在r中实现一个广义的“切换方程”(Gerber and Green 2012,第2章)。
我有一个分类变量Z,它有k> 2个值。
我有k列名Y_1,Y_2,... Y_k。
我想创建一个变量Y,从每列中选择“正确”的值。也就是说,如果Z为1,则将Y_1值放入Y中。
我有一个循环的解决方案,但它很烦人。用一个衬垫是否有超级甜蜜的方式来做到这一点?没有嵌套的ifelse,请等。
N <- 100
df <- data.frame(
Z = sample(1:3, N, replace = TRUE),
Y_1 = rnorm(N),
Y_2 = rnorm(N),
Y_3 = rnorm(N)
)
# an annoying solution
df <- within(df,{
Y <- rep(NA, nrow(df))
Y[Z == 1] <- Y_1[Z == 1]
Y[Z == 2] <- Y_2[Z == 2]
Y[Z == 3] <- Y_3[Z == 3]
})
head(df)
产生:
Z Y_1 Y_2 Y_3 Y
1 3 0.89124772 1.4377700 0.05226285 0.05226285
2 1 0.89186873 -0.6984839 -0.86141525 0.89186873
3 1 -0.01315678 1.5193461 0.18290065 -0.01315678
4 3 -0.57857274 -1.4445197 2.03764943 2.03764943
5 3 -0.19793692 -0.1818225 1.10270877 1.10270877
6 2 1.48291431 2.7264541 0.70129357 2.72645413
编辑:我喜欢Weihuang Wong的方法df$Y <- sapply(split(df, 1:nrow(df)), function(x) x[, paste0("Y_", x$Z)])
,部分原因是它不依赖于位置而是依赖于列名。到目前为止,所有提供的答案都使用了列位置....我有点担心sapply(split())
很慢,但也许我疯了?
答案 0 :(得分:2)
df$Y <- apply(df, 1, function(x) x[x[1]+1] )
head(df)
# Z Y_1 Y_2 Y_3 Y
#1 1 -0.8598997 -0.3180947 1.9374462 -0.8598997
#2 2 -0.2392902 0.2266245 0.2364991 0.2266245
#3 1 -0.8733609 -1.3892361 0.3351359 -0.8733609
#4 3 -0.6533548 -1.1042993 -0.2906852 -0.2906852
#5 1 -1.7424126 -0.2101860 0.1198945 -1.7424126
#6 2 -1.9746651 -0.4308746 -0.7849773 -0.4308746
答案 1 :(得分:2)
不完全是1行,但是
get_result <- function(dfrow){
x <- unlist(dfrow[,1:4])
Y <- x[x[1] + 1]
}
library(purrr)
newdf <- by_row(df, get_result)
答案 2 :(得分:1)
这可以使用AVCaptureSessionPresetPhoto
索引
username=user321@user.com&password=somepassword&grant_type=password
row/column
答案 3 :(得分:0)
OP在这里。
我用手工解决了黄伟煌提出的“ind_split”解决方案。我也是通过“团体”来做的:
N <- 100000
df <- data.frame(
Z = sample(1:3, N, replace = TRUE),
Y_1 = rnorm(N),
Y_2 = rnorm(N),
Y_3 = rnorm(N)
)
ind_split <-
system.time({
df$Y <- sapply(split(df, 1:nrow(df)), function(x) x[, paste0("Y_", x$Z)])
head(df)
})
revealer <-
function(list_element){
col_name <- paste0("Y_", list_element[1, "Z"])
list_element$Y <- list_element[,col_name]
return(list_element)
}
group_split <-
system.time({
split_list <- split(df, df$Z)
df <- do.call(what = rbind, lapply(split_list, revealer))
head(df)
})
by_hand <-
system.time({
# an annoying solution
df <- within(df,{
Y <- rep(NA, nrow(df))
Y[Z == 1] <- Y_1[Z == 1]
Y[Z == 2] <- Y_2[Z == 2]
Y[Z == 3] <- Y_3[Z == 3]
})
head(df)
})
ind_split
group_split
by_hand
时间进入
> ind_split
user system elapsed
1.023 0.083 1.136
> group_split
user system elapsed
0.011 0.002 0.013
> by_hand
user system elapsed
0.001 0.000 0.001
手工烦人的方法更快,这对我来说太疯狂了!按群体分割比个人分割要快。
答案 4 :(得分:0)
这里最后添加的内容是通过使用match
和names
(基于另一个previously suggested by Akrun并由我自己修改的解决方案),根据Akrun的答案而建立的,但不使用职位编号: / p>
df$Y <- df[cbind(1:nrow(df), match(paste0('Y_', df$Z), names(df)))]