ifelse dplyr显示错误的输出

时间:2017-03-28 05:46:29

标签: r if-statement dplyr

我想创建一个新列,选择三个可能列的最小值,然后根据条件使用addsubtract

我有下一个名为df的数据框:

     a    b    c
1  0.60 0.27 0.14
2  0.48 0.32 0.21
3  0.42 0.24 0.35
4  0.28 0.33 0.41
5  0.52 0.28 0.22
6  0.34 0.30 0.37
7  0.38 0.28 0.35
8  0.34 0.28 0.40
9  0.53 0.26 0.22
10 0.17 0.27 0.58
11 0.34 0.35 0.33
12 0.19 0.27 0.56
13 0.56 0.29 0.17
14 0.55 0.28 0.19
15 0.29 0.24 0.48
16 0.23 0.31 0.47
17 0.40 0.32 0.28
18 0.50 0.27 0.24
19 0.45 0.28 0.27
20 0.68 0.26 0.05
21 0.40 0.32 0.28
22 0.23 0.26 0.50
23 0.46 0.33 0.20
24 0.46 0.24 0.28
25 0.44 0.24 0.31
26 0.46 0.26 0.27
27 0.30 0.29 0.40
28 0.45 0.20 0.34
29 0.53 0.27 0.20
30 0.33 0.34 0.33
31 0.20 0.26 0.55
32 0.65 0.29 0.06
33 0.45 0.24 0.32
34 0.30 0.26 0.45
35 0.20 0.36 0.45
36 0.38 0.16 0.38

每行必须总和为1,但正如您所注意到的,只有其中一些满足该条件。

df_total <- rowSums(df[c("a", "b", "c")])
print(df_total)
   1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19 
1.01 1.01 1.01 1.02 1.02 1.01 1.01 1.02 1.01 1.02 1.02 1.02 1.02 1.02 1.01 1.01 1.00 1.01 1.00 
  20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36 
0.99 1.00 0.99 0.99 0.98 0.99 0.99 0.99 0.99 1.00 1.00 1.01 1.00 1.01 1.01 1.01 0.92

例如,在df的第36行中,我需要将最低值(即0.16)加上一个数字,该数字将ab和{{1总和为1.

我想有一种更简单的方法可以做到这一点,但到目前为止我已经完成了这段代码而且它不起作用......为什么?

c

这是输出:

df_total <- rowSums(df[c("a", "b", "c")])

df_for_sum <- df_total[df_total > 1] - 1  #The ones which are above 1
df_for_minus <- -(df_total[df_total < 1]) + 1  #The ones which are below 1 
equal_to_100 <- df_total[df_total == 1]  #The ones which are ok

df <- df %>%
  mutate(d = ifelse(rowSums(df[c("a","b","c")]) > 1,
                            apply(df[rowSums(df[c("a","b","c")]) > 1,], 1, min) - df_for_sum,
                    ifelse(rowSums(df[c("a","b","c")]) < 1,
                           apply(df[rowSums(df[c("a","b","c")]) < 1,], 1, min) + df_for_minus,
                           ifelse(rowSums(df[c("a","b","c")]) == 1,
                                  apply(df[rowSums(df[c("a","b","c")]) == 1,], 1, min), ""))))

有什么想法?任何更简单的方法?

2 个答案:

答案 0 :(得分:2)

您想首先计算超额差异:

df$d <- apply(df, 1, min) + diff

然后将其添加到最低限度:

class CollectorUDAF() extends UserDefinedAggregateFunction {

  // Input Data Type Schema
  def inputSchema: StructType = new StructType().add("value", DataTypes.DoubleType).add("y", DataTypes.DoubleType)

  // Intermediate Schema
  val bufferFields : util.ArrayList[StructField] = new util.ArrayList[StructField]
  val bufferStructField : StructField = DataTypes.createStructField("array", DataTypes.createArrayType(DataTypes.StringType, true), true)
  bufferFields.add(bufferStructField)
  def bufferSchema: StructType = DataTypes.createStructType(bufferFields)

  // Returned Data Type .
  def dataType: DataType = DataTypes.createArrayType(DataTypes.DoubleType)

  // Self-explaining
  def deterministic = true

  // This function is called whenever key changes
  def initialize(buffer: MutableAggregationBuffer) = {
    buffer(0, new java.util.ArrayList[Double])
  }

  // Iterate over each entry of a group
  def update(buffer: MutableAggregationBuffer, input: Row) = {
    val DoubleList: util.ArrayList[Double]  = new util.ArrayList[Double](buffer.getList(0))
    DoubleList.add(input.getDouble(0))
    DoubleList.add(input.getDouble(1))
    buffer.update(0, DoubleList)
  }

  def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
    buffer1.update(0, buffer1.getList(0).toArray() ++ buffer2.getList(0).toArray())
  }
  // Called after all the entries are exhausted.
  def evaluate(buffer: Row) = {
    buffer.getList(0).toArray()
  }
}

答案 1 :(得分:1)

以下是dplyr中没有ifelse的方法:

df2 <- df1 %>%
  mutate(difference = 1-rowSums(.) ) %>%
  rowwise() %>%
  mutate(d = min(c(a,b,c))+difference )
df2
       a     b     c difference     d
   (dbl) (dbl) (dbl)      (dbl) (dbl)
1   0.60  0.27  0.14      -0.01  0.13
2   0.48  0.32  0.21      -0.01  0.20
3   0.42  0.24  0.35      -0.01  0.23
4   0.28  0.33  0.41      -0.02  0.26
5   0.52  0.28  0.22      -0.02  0.20
6   0.34  0.30  0.37      -0.01  0.29
7   0.38  0.28  0.35      -0.01  0.27
8   0.34  0.28  0.40      -0.02  0.26
9   0.53  0.26  0.22      -0.01  0.21
10  0.17  0.27  0.58      -0.02  0.15
11  0.34  0.35  0.33      -0.02  0.31
12  0.19  0.27  0.56      -0.02  0.17
13  0.56  0.29  0.17      -0.02  0.15
14  0.55  0.28  0.19      -0.02  0.17
15  0.29  0.24  0.48      -0.01  0.23
16  0.23  0.31  0.47      -0.01  0.22
17  0.40  0.32  0.28       0.00  0.28
18  0.50  0.27  0.24      -0.01  0.23
19  0.45  0.28  0.27       0.00  0.27
20  0.68  0.26  0.05       0.01  0.06
21  0.40  0.32  0.28       0.00  0.28
22  0.23  0.26  0.50       0.01  0.24
23  0.46  0.33  0.20       0.01  0.21
24  0.46  0.24  0.28       0.02  0.26
25  0.44  0.24  0.31       0.01  0.25
26  0.46  0.26  0.27       0.01  0.27
27  0.30  0.29  0.40       0.01  0.30
28  0.45  0.20  0.34       0.01  0.21
29  0.53  0.27  0.20       0.00  0.20
30  0.33  0.34  0.33       0.00  0.33
31  0.20  0.26  0.55      -0.01  0.19
32  0.65  0.29  0.06       0.00  0.06
33  0.45  0.24  0.32      -0.01  0.23
34  0.30  0.26  0.45      -0.01  0.25
35  0.20  0.36  0.45      -0.01  0.19
36  0.38  0.16  0.38       0.08  0.24

数据:

df1 <-read.table(text="a  b   c
0.6 0.27 0.14
0.48 0.32 0.21
0.42 0.24 0.35
0.28 0.33 0.41
0.52 0.28 0.22
0.34 0.3 0.37
0.38 0.28 0.35
0.34 0.28 0.4
0.53 0.26 0.22
0.17 0.27 0.58
0.34 0.35 0.33
0.19 0.27 0.56
0.56 0.29 0.17
0.55 0.28 0.19
0.29 0.24 0.48
0.23 0.31 0.47
0.4 0.32 0.28
0.5 0.27 0.24
0.45 0.28 0.27
0.68 0.26 0.05
0.4 0.32 0.28
0.23 0.26 0.5
0.46 0.33 0.2
0.46 0.24 0.28
0.44 0.24 0.31
0.46 0.26 0.27
0.3 0.29 0.4
0.45 0.2 0.34
0.53 0.27 0.2
0.33 0.34 0.33
0.2 0.26 0.55
0.65 0.29 0.06
0.45 0.24 0.32
0.3 0.26 0.45
0.2 0.36 0.45
0.38 0.16 0.38",header=TRUE,stringsAsFactors=FALSE)