根据其他列选择值

时间:2018-12-10 16:51:23

标签: r

我有一个数据框(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)))))))

2 个答案:

答案 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,表示“不是数字”