在数据框中使用Ifelse

时间:2016-05-18 20:22:44

标签: r if-statement dataframe

我使用的数据框是

> df <- data.frame(Name=c("Joy","Jane","Jack","Jad"),M1=c(10,40,55,90))
> df
  Name M1
1  Joy 10
2 Jane 40
3 Jack 55
4  Jad 90

> df$Final <- ifelse(df$M1<=50,60,max(75,df$M1))
> df
  Name M1 Final
1  Joy 10    60
2 Jane 40    60
3 Jack 55    90
4  Jad 90    90

如果M1值小于或等于50,那么我需要60作为我的最终值,而如果M1值大于50则我需要最大值(75,M1)。在Jack的情况下,M1是55,所以我应该得到最大值(75,55),这是75.我认为它给了我整个M1列的最大值。怎么避免这个?

期望的输出

  Name M1 Final
1  Joy 10    60
2 Jane 40    60
3 Jack 55    75
4  Jad 90    90

5 个答案:

答案 0 :(得分:8)

您也可以使用pmax代替max

ifelse(df$M1 <= 50, 60, pmax(75, df$M1))

在帮助文件中,pmax需要

  

一个或多个向量(或矩阵)作为参数,并返回单个向量,给出向量的“并行”最大值。结果的第一个元素是所有参数的第一个元素的最大值......结果的第二个元素是所有参数的第二个元素的最大值......依此类推。

因此ifelse的第三个参数,即“else”值,是成对最大值75(根据需要再循环多次)和df $ M1的值。

答案 1 :(得分:3)

怎么样:

ifelse(df$M1<=50,60,ifelse(df$M1>75,df$M1,75))

答案 2 :(得分:3)

你实际上是在描述像...这样的规则。

  • 最多50个,替换为60个
  • 最多75个,替换为75
  • 最多x,替换为y
  • ...

如果我们将规则放入data.frame,它更明确,可能允许更有效地推导结果(而不是计算许多不等式)。这有两种方式:

<强> findInterval

m = data.frame(up_to = c(50, 75), replace_with = c(60, 75))

df$Final = df$M1
r = m$replace_with[ findInterval(df$M1, m$up_to) + 1L ]
df$Final = replace(df$M1, !is.na(r), na.omit(r))

data.table滚动加入

library(data.table)    
setDT(df)

m = data.table(up_to = c(50, 75), replace_with = c(60, 75))

df[, Final := M1]
r = m[df, on=c(up_to = "M1"), roll=-Inf][!is.na(replace_with), Final := replace_with]$Final
df[, Final := r]

答案 3 :(得分:0)

如果d$M1仅包含正{null} integer,则使用查找可能会更有效:

lookup <-  c(rep(60, 50),rep(75, 25), 76:max(df$M1,76))
lookup[df$M1]

如果它还包含否定或空integer s:

lookup <-  c(rep(60, 50-min(df$M1)+1),rep(75, 25), 76:max(df$M1,76))
lookup[df$M1-min(df$M1)+1]

答案 4 :(得分:-1)

您可以使用dplyrrowwise

library(dplyr)

df %>%
  rowwise() %>%
  mutate(Final = ifelse(M1<=50,60,max(75,M1)))