我有一个数据框(df,其示例如下所示)。我想从a1,b1和c1列中选择值并取平均值,如果a2,b2和c2中的值为正。例如,在df的第一行中,a2,b2和c2中的所有值均为正,然后我选择a1,b1和c1中的相应值并将它们取平均值。结果是0.4933。在第二列中,只有c2中的值为正,然后选择c1中的值(0.01)。
a1 b1 c1 a2 b2 c2 desired outcome
0.51 0.49 0.48 0.05 0.03 0.09 0.493333
0.33 0.31 0.3 -0.03 -0.05 0.01 0.01
0.22 0.2 0.19 0.04 0.02 0.08 0.203333
0.54 0.52 0.51 -0.05 0.08 -0.01 0.08
0.45 0.43 0.42 -0.03 -0.05 0.01 0.01
下面是列出所有方案的代码。我正在寻找可以处理更多列的更有效的代码。
df2 <- df1 %>% select(c(a2,b2,c2)) %>%
mutate(outcome = ifelse(a2 >0 & b2>0 & c2>0, mean(a1,b1,c1),
ifelse(a2>0 & b2>0 &c2<0, mean(a1,b1),
ifelse(a2>0&b2<0&c2<0, mean(a1),
ifelse(a2<0&b2>0&c2>0, mean(b2,c2),
ifelse(a2<0&b2<0&c2>0, mean(c2),
mean(b2)))))))
答案 0 :(得分:2)
1)在这里Mean
进行一行计算,我们将其分别应用于每一行。我们假设您要在前3列中将其后3列中对应列为正的元素置零,然后取其平均值。
Mean <- function(x) mean(x[1:3] * (x[4:6] > 0))
transform(df2, desired = apply(df2, 1, Mean))
给予:
a1 b1 c1 a2 b2 c2 desired
1 0.51 0.49 0.48 0.05 0.03 0.09 0.4933333
2 0.33 0.31 0.30 -0.03 -0.05 0.01 0.1000000
3 0.22 0.20 0.19 0.04 0.02 0.08 0.2033333
4 0.54 0.52 0.51 -0.05 0.08 -0.01 0.1733333
5 0.45 0.43 0.42 -0.03 -0.05 0.01 0.1400000
2)或不使用apply
:
transform(df2, desired = rowMeans(df2[1:3] * (df2[4:6] > 0)))
给予:
a1 b1 c1 a2 b2 c2 desired
1 0.51 0.49 0.48 0.05 0.03 0.09 0.4933333
2 0.33 0.31 0.30 -0.03 -0.05 0.01 0.1000000
3 0.22 0.20 0.19 0.04 0.02 0.08 0.2033333
4 0.54 0.52 0.51 -0.05 0.08 -0.01 0.1733333
5 0.45 0.43 0.42 -0.03 -0.05 0.01 0.1400000
输入df2
以可复制的形式:
Lines <- "
a1 b1 c1 a2 b2 c2
0.51 0.49 0.48 0.05 0.03 0.09
0.33 0.31 0.3 -0.03 -0.05 0.01
0.22 0.2 0.19 0.04 0.02 0.08
0.54 0.52 0.51 -0.05 0.08 -0.01
0.45 0.43 0.42 -0.03 -0.05 0.01"
df2 <- read.table(text = Lines, header = TRUE)
答案 1 :(得分:1)
子集只是基于某些条件选择某个值,但这不必是基于该值本身的条件。
听起来很难,但举一个例子很容易:
df[1,1:3][df[1,4:6]>0]
我们从第一行开始获取前三列,但仅对应的值为TRUE
。相应的值是第一行第4-6列“您是否积极”的答案。
对于第一行,所有三个都是TRUE
,但是对于第二行,我们只有一个值:.3。
现在我们可以取均值,如果要对所有行都取平均值,可以使用sapply:
outcome <- sapply(1:nrow(df), function(i) {mean(df[i,1:3][df[i,4:6]>0])})
仅当a2,b2和c2均为负三行时,mean
会返回NaN
,表示“不是数字”