我仍在与R一起迈出第一步,发现SO是一个很好的工具,可以学习更多知识并找到问题的答案。对于这个我虽然没有找到任何好的解决方案。
我有一个可以简化为这种结构的数据框:
set.seed(10)
df <- data.frame(v1 = rep(1:2, times=3),
v2 = c("A","B","B","A","B","A"),
v3 = sample(1:6),
xA_1 = sample(1:6),
xA_2 = sample(1:6),
xB_1 = sample(1:6), xB_2 = sample(1:6))
df因此看起来像这样:
> df
v1 v2 v3 xA_1 xA_2 xB_1 xB_2
1 1 A 4 2 1 3 3
2 2 B 2 6 3 5 4
3 1 B 5 3 2 4 5
4 2 A 3 5 4 2 1
5 1 B 1 4 6 6 2
6 2 A 6 1 5 1 6
我现在希望R创建第四个变量,它取决于v1和v2的值。我通过使用以下代码实现了这一点:
df <- data.table(df)
df[, v4 := ifelse(v1 == 1 & v2 == "A", v3*xA_1,
ifelse(v1 == 1 & v2 == "B", v3*xB_1,
ifelse(v1 == 2 & v2 == "A", v3*xA_2,
ifelse(v1 == 2 & v2 == "B", v3*xB_2, v3*1))))]
因此,通过将v3与包含v1和v2值的列相乘来创建v4
(例如,对于第1行:v1=1 and v2=A thus multiply v3=4 with xA_1=2 -> 8
)。
> df$v4
[1] 8 8 20 12 6 30
很明显,当v1和v2实际上具有比本例中更多不同的值时,我的ifelse方法很乏味。所以我正在寻找一种有效的方式告诉R if v1 == y & v2 == z, multiply v3 with column xy_z
。
我尝试编写for循环,编写一个y和z作为索引并使用apply函数的函数。然而,这一切都没有按照要求发挥作用。
我很感激任何想法!
答案 0 :(得分:2)
这是一个基本R选项:
i <- paste0("x", df$v2, "_", df$v1)
df$v4 <- df$v3 * as.numeric(df[cbind(1:nrow(df), match(i, names(df)))])
对于下面提供的示例数据,它会创建一个列v4
:
> df$v4
[1] 25 12 2 6 3 10
或者,如果您希望包含“else”条件,则在没有匹配列名的情况下乘以1:
i <- paste0("x", df$v2, "_", df$v1)
tmp <- as.numeric(df[cbind(1:nrow(df), match(i, names(df)))])
df$v4 <- df$v3 * ifelse(is.na(tmp), 1, tmp)
示例数据:
df <- structure(list(v1 = c(1L, 2L, 1L, 2L, 1L, 2L), v2 = structure(c(1L,
2L, 2L, 1L, 2L, 1L), .Label = c("A", "B"), class = "factor"),
v3 = c(5L, 4L, 1L, 6L, 3L, 2L), xA_1 = c(5L, 6L, 3L, 1L,
2L, 4L), xA_2 = c(6L, 4L, 2L, 1L, 3L, 5L), xB_1 = c(4L, 6L,
2L, 5L, 1L, 3L), xB_2 = c(5L, 3L, 2L, 4L, 1L, 6L)), .Names = c("v1",
"v2", "v3", "xA_1", "xA_2", "xB_1", "xB_2"), row.names = c(NA,
-6L), class = "data.frame")
答案 1 :(得分:2)
这是一个标准的“广泛”表格问题 - 您想要的更难做,但数据“融化”时很容易:
dt = as.data.table(df)
melt(dt, id.vars = c('v1', 'v2', 'v3'))[variable == paste0('x', v2, '_', v1)
][dt, on = c('v1', 'v2', 'v3'), v3 * value]
#[1] 8 8 20 12 6 30
答案 2 :(得分:0)
你可以试试这个:
v4 <- c()
for(i in 1:nrow(df)){
col <- paste("x",df$v2[i],"_",df$v1[i],sep="")
v4 <- c(v4,df$v3[i]*df[i,col])
}
df$v4 <- v4