【问题标题】:Recoding turns everything into the same value in R重新编码将所有内容转换为 R 中的相同值
【发布时间】:2020-05-18 20:23:14
【问题描述】:

我正在练习 R,我创建了一个新列,其中包含连续数字,称为 ROI,并希望将数字值重新编码为 R 中的字符串值,如下所示:

df = mutate(diabetes_df, ROI = ifelse(ROI < 18.5, 'Under', ROI))
df = mutate(diabetes_df, ROI = ifelse(ROI >= 18.5 & ROI <= 25, 'average', ROI))

diabetes_df = mutate(diabetes_df, ROI = ifelse(ROI > 25 & BMI <= 30, 'above average', ROI))

这可以正常工作,并且在满足条件的任何地方都会显示这些单词,但是当我输入最后一个ifelse 语句时:

df = mutate(diabetes_df, ROI = ifelse(ROI > 30, 'OVER', ROI))

它将我创建的新列中的每个值都转换为OVER 值。我想知道是否有人知道如何制作它,以便它只会说OVER 满足条件?

【问题讨论】:

  • @akrun ROI 是数字,我很抱歉没有早点说明

标签: r if-statement dplyr recode


【解决方案1】:
  • 如果 ROI 是数字列,则问题是您正在用文本值覆盖数字列。
  • 如果 ROI 不是数字列,则文本字符串的不等式比较与您的假设不同。

请注意,所有命令都采用以下形式:df = mutate(df, ROI = ifelse(ROI &lt;condition&gt;, 'label', ROI)。这意味着您正在覆盖原始 ROI 值,而替换后的值将用于后续比较。

假设 df 只有一行 ROI = 10 然后:

# df:
# ROI = 10

df2 = mutate(df, ROI = ifelse(ROI < 18.5, 'Under', ROI))
# compares 10 < 18.5
# replaces 10 with 'Under'

# df2:
# ROI = 'Under'

df3 = mutate(df2, ROI = ifelse(ROI > 30, 'OVER', ROI))
# compares 'Under' > 30
# After standardizing formats, compares 'Under' > '30' (conversion to string)
# replaces 'Under' with 'OVER'

两种可能的解决方案:

  1. 写到不同的列,这是个好习惯
df %>%
  mutate(ROI_label = NA) %>%
  mutate(ROI_label = ifelse(ROI < 18.5, 'Under', ROI_label)) %>%
  mutate(ROI_label = ifelse(ROI >= 18.5 & ROI <= 25, 'average', ROI_label)) %>%
  mutate(ROI_label = ifelse(ROI > 25 & BMI <= 30, 'above average', ROI_label)) %>%
  mutate(ROI_label = ifelse(ROI > 30, 'OVER', ROI_label))
  1. 使用case_when,这也是很好的做法
df %>%
  mutate(ROI = case_when(ROI < 18.5 ~ 'Under',
                         ROI >= 18.5 & ROI <= 25 ~ 'average',
                         ROI > 25 & BMI <= 30 ~ 'above average',
                         ROI > 30 ~ 'OVER'))

更好的是,写到不同的列并使用case_when

【讨论】:

  • ROI 是一个数值,抱歉没有说明
  • 也许您可以使用cutfindInterval 使其更简单
  • 您知道如何将该列添加到现有数据集中吗?似乎当我运行此代码时,它会在控制台中创建列,但不会在实际数据集中创建列
  • 您需要分配输出:df &lt;- df %&gt;% mutate(...
【解决方案2】:

我们可以用mtcars 数据框复制问题。第三个mutate() 语句中的以下代码导致所有行都将wt 值设置为High,因为在第一个mutate() 之后,wt 列是字符值向量。

library(dplyr)
data(mtcars)
mtcars <- mutate(mtcars,wt = ifelse(wt < 2.6,"Low", wt))
# at this point, wt is character
str(mtcars$wt)


> str(mtcars$wt)
 chr [1:32] "2.62" "2.875" "Low" "3.215" "3.44" "3.46" "3.57" "3.19" "3.15" ...

到第三个mutate(),基于字符串比较LowMedium 的字符串值大于数字3.61,所有行都满足if_else() 的TRUE 条件。

mtcars <- mutate(mtcars, wt = ifelse( 2.6 <= wt & wt <= 3.61,"Medium",wt))
mtcars <- mutate(mtcars, wt = ifelse( wt > 3.61,"High",wt))

...和输出:

> head(mtcars)
                   mpg cyl disp  hp drat   wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 High 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 High 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 High 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 High 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 High 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 High 20.22  1  0    3    1

我们可以通过使用case_when() 来防止这种行为,这会在一次数据传递中与wt 的数字版本进行所有比较。

# use case_when()
data(mtcars)
mtcars %>% mutate(wt = case_when(
     wt < 2.6 ~ "Low",
     wt >= 2.6 & wt <= 3.61 ~ "Medium",
     wt > 3.61 ~ "High"
)) %>% head(.)

...和输出:

head(.)
                   mpg cyl disp  hp drat     wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 Medium 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 Medium 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85    Low 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 Medium 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 Medium 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 Medium 20.22  1  0    3    1
> 

从 cmets 到这个答案,OP 不清楚如何将更改的列保存到现有数据框中。下面的代码 sn-p 解决了这个问题。

data(mtcars)
mtcars %>% mutate(wt = case_when(
     wt < 2.6 ~ "Low",
     wt >= 2.6 & wt <= 3.61 ~ "Medium",
     wt > 3.61 ~ "High"
)) -> mtcars

【讨论】:

  • 如果您不想创建一个新列,因为您已经有一个存在的列? @Len Greski
  • mtcars 数据框中,wt 是一个现有的数字列。
  • 我的意思是说你会如何将该列添加到现有数据集中?似乎它显示在控制台中,但没有显示在实际数据集中
猜你喜欢
  • 1970-01-01
  • 2015-07-26
  • 2015-09-29
  • 1970-01-01
  • 2013-01-10
  • 1970-01-01
  • 2021-12-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多