重新编码将 R 中的所有内容都变成相同的值
Recoding turns everything into the same value in R
我正在练习 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
?
- 如果 ROI 是数字列,问题是您正在用文本值覆盖数字列。
- 如果 ROI 不是数字列,则文本字符串的不等式比较与您假设的方式不同。
请注意,您所有的命令都采用以下形式:df = mutate(df, ROI = ifelse(ROI <condition>, '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'
两种可能的解决方案:
- 写入不同的列,这是一个好习惯
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))
- 使用
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
。
我们可以用 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()
所有行都满足 if_else()
的 TRUE 条件,基于字符串比较,其中 Low
和 Medium
的字符串值是大于数字 3.61。
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
>
从对该答案的评论来看,OP 不清楚如何将更改的列保存到现有数据框中。下面的代码片段解决了这个问题。
data(mtcars)
mtcars %>% mutate(wt = case_when(
wt < 2.6 ~ "Low",
wt >= 2.6 & wt <= 3.61 ~ "Medium",
wt > 3.61 ~ "High"
)) -> mtcars
我正在练习 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
?
- 如果 ROI 是数字列,问题是您正在用文本值覆盖数字列。
- 如果 ROI 不是数字列,则文本字符串的不等式比较与您假设的方式不同。
请注意,您所有的命令都采用以下形式:df = mutate(df, ROI = ifelse(ROI <condition>, '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'
两种可能的解决方案:
- 写入不同的列,这是一个好习惯
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))
- 使用
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
。
我们可以用 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()
所有行都满足 if_else()
的 TRUE 条件,基于字符串比较,其中 Low
和 Medium
的字符串值是大于数字 3.61。
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
>
从对该答案的评论来看,OP 不清楚如何将更改的列保存到现有数据框中。下面的代码片段解决了这个问题。
data(mtcars)
mtcars %>% mutate(wt = case_when(
wt < 2.6 ~ "Low",
wt >= 2.6 & wt <= 3.61 ~ "Medium",
wt > 3.61 ~ "High"
)) -> mtcars