基于其他列的if-else评估在data.frame中创建新列

基于其他列的if-else评估在data.frame中创建新列,r,dataframe,if-statement,switch-statement,R,Dataframe,If Statement,Switch Statement,我正在尝试向数据帧添加一个新列(x_new),该列取决于“定义”列中给定的值。定义列x_definition包含以下记录类型之一: -常数 -描述所需操作的字符串 -NA 我希望生成的列,xu new,如下所示: -如果x_定义为NA,则x_新建仍为NA。 -如果x_定义是一个字符串,则需要进行特定的计算。例如,如果它是“等于”,那么结果应该是z,或者如果它的“第三个”,那么x\u new应该是z/3。还有不止这些定义表明需要更复杂的z函数。 -如果x_definition是任何数字,那么x_n

我正在尝试向数据帧添加一个新列(
x_new
),该列取决于“定义”列中给定的值。定义列
x_definition
包含以下记录类型之一: -常数 -描述所需操作的字符串 -NA

我希望生成的列,
xu new
,如下所示: -如果
x_定义
为NA,则
x_新建
仍为NA。 -如果
x_定义
是一个字符串,则需要进行特定的计算。例如,如果它是
“等于”
,那么结果应该是
z
,或者如果它的
“第三个”
,那么
x\u new
应该是z/3。还有不止这些定义表明需要更复杂的z函数。 -如果
x_definition
是任何数字,那么
x_new
应该就是该数字

我编写了以下代码来处理这些情况,但这是一组嵌套的
ifelse
语句。我正在寻找一种方法

data <- data %>% mutate(x_new = ifelse(
  is.na(x_definition), NA, ifelse(
    x_definition=='equal_to_z', z, ifelse(
      x_definition=='third_of_z', z/3, NA
      )
    )
  )
)

解决这个问题的合适方法是什么?

我认为
case\u当
正是你想要的

data = data %>%
    mutate(x_new = case_when(is.na(x_definition) ~ NA,
                             x_definition == 'equal_to_z' ~ z,
                             x_definition == 'third_of_z' ~ z / 3,
                             !is.na(as.numeric(x_definition)) ~ as.numeric(x_definition)))

是的,这是一个非常普遍的需求,它有一个非常好的解决方案

你的逻辑是:

如果x_的定义是NA,那么x_new仍然是NA如果x_定义是一个字符串,那么它需要一定的计算。例如,如果它的“等于”结果应该是z,或者如果它的“第三个”结果应该是z,那么x_new应该是z/3。还有不止这些定义表明需要更复杂的z函数。-如果x_定义是任何数字,那么x_new应该就是该数字

我可以把它改写成

np.nan if row['x_definition'] is np.nan 
else row['z'] if row['x_definition'] == 'equal_to_z' 
else row['z']/3 if row['x_definition'] == 'third_of_z' 
else row['x_definition'] if isinstance('row['x_definition'], int) 
else np.nan
那你就可以了

df['x_new'] = df.apply(lambda row: np.nan if row['x_definition'] is np.nan 
                    else row['z'] if row['x_definition'] == 'equal_to_z' 
                    else row['z']/3 if row['x_definition'] == 'third_of_z' 
                    else row['x_definition'] if isinstance('row['x_definition'], int) 
                    else np.nan, axis=1)
或者如果你想变得更优雅

def logic_for_x_new(row):
 ...
 return x_new

df['x_new'] = df.apply(logic_for_x_new, axis=1)
注意如何在Pandas中检查nan,我使用的技巧是,当x为nan时,x==x为false(注意这一点)

使用axis=1 in.apply()使函数逐行应用,并且每一行基本上是一个按列名索引的字典。
def logic_for_x_new(row):
 ...
 return x_new

df['x_new'] = df.apply(logic_for_x_new, axis=1)