基于其他列的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)