ds <- read.csv(file="~/Desktop/abalone.csv)
Sex Length
M 12.1
F 11.2
12.1 F
I 11.2
12.1 11.2
11.2 I数据集包含两个列,分别是性别和长度。性列包含三个值,即"F“(女性)、"M”(男性)和"I“(婴儿)。数据集已被修改,有几个问题我需要解决。我需要解决以下问题
question)
的
我解决错域值的想法是根据长度的值在两列之间交换数据。假设长度中的值是"F“、"M”和"I",则将数据与性别交换。我真的不知道如何根据长度的值在这两列之间交换数据。
swap_if <-function (ds$Sex, ds$Length, missing = NA){
a <- ds$Length == "M"
b <- ds$Length == "F"
c <- ds$Length == "I"}
swap_if(ds$Sex, ds$Length)但这行不通。有人能帮我做这个吗。非常感谢
之后,我需要删除无效的值。第五行第一列的值无效,因为“性”的值必须为“F”、“M”和“I”。
#remove wrong format /invalid data in sex column
ds <- ds[!str_detect(ds$Sex, '([0-9])'), ]
ds$Sex <- as.factor(ds$Sex)^此代码可以删除格式值无效/错误的行。
发布于 2020-07-03 03:52:32
尽管我建议(修复问题的根源),但这里有一个尝试恢复的方法。
column <- grepl("^[.0-9]+$", dat[,1])
column
# [1] FALSE FALSE FALSE TRUE FALSE TRUE TRUE FALSE
dat2 <- data.frame(Sex = dat[cbind(seq_len(nrow(dat)),1+column)], Length = dat[cbind(seq_len(nrow(dat)),2-column)])
dat2$Length <- as.numeric(dat2$Length)
dat2
# Sex Length
# 1 M 12.2
# 2 F 14.1
# 3 M 14.6
# 4 F 9.0
# 5 L 12.1
# 6 M 10.1
# 7 F 11.0
# 8 M 11.9一种潮流选择:
library(dplyr)
dat %>%
mutate(
swap = grepl("[^.[:digit:]]", Length),
Length2 = if_else(swap, Sex, Length),
Sex2 = if_else(swap, Length, Sex)
) %>%
transmute(
Sex = Sex2,
Length = as.numeric(Length2)
)
# Sex Length
# 1 M 12.2
# 2 F 14.1
# 3 M 14.6
# 4 F 9.0
# 5 L 12.1
# 6 M 10.1
# 7 F 11.0
# 8 M 11.9数据:
dat <- structure(list(Sex = c("M", "F", "M", "9", "L", "10.1", "11",
"M"), Length = c("12.2", "14.1", "14.6", "F", "12.1", "M", "F",
"11.9")), class = "data.frame", row.names = c(NA, -8L))发布于 2020-07-03 04:28:39
下面是另一个与tidyverse一起工作的解决方案。它创建一个小助手列,该列将在末尾被删除。
library(tidyverse)
# create the inverse of `%in%`
`%!in%` = Negate(`%in%`)
df %>%
# create a helper column, will be deleted
mutate(help = Sex) %>%
mutate(Sex = case_when(
Sex %!in% c('L', 'M', 'F') ~ Length,
TRUE ~ Sex
)) %>%
mutate(Length = case_when(
Length %in% c('L', 'M', 'F') ~ help,
TRUE ~ Length
)) %>%
# delete helper column
select(-help)
#> Sex Length
#> 1 M 12.2
#> 2 F 14.1
#> 3 M 14.6
#> 4 F 9
#> 5 L 12.1
#> 6 M 10.1
#> 7 F 11
#> 8 M 11.9发布于 2020-07-03 03:56:20
您可以使用if -然后设置一个for循环来检查字符变量是否可以安全地转换为数字。如果是这样的话,它属于length。
sex = c('M','F', 'M', 9, 'L', 10.1, 11, 'M')
length = c(12.2, 14.1, 14.6, 'F', 12.1, 'M', 'F', 11.9)
df = data.frame(sex, length)
str(df)
df$sex.c = 0
df$length.c = 0
for (i in 1:length(df$sex)){
if (!is.na(as.numeric(df$sex[i]))){
df$sex.c[i] = df$length[i]
df$length.c[i] = df$sex[i]
} else {
df$sex.c[i] = df$sex[i]
df$length.c[i] = df$length[i]
}
}
df$sex = df$sex.c
df$length = df$length.c
df = df[,1:2]请注意,这将创建一个NAs introduced by coercion警告。如果这让您感到困扰,那么您可以通过更改for循环来抑制它们,如下所示:
for (i in 1:length(df$sex)){
if (suppressWarnings(!is.na(as.numeric(df$sex[i])))){
df$sex.c[i] = df$length[i]
df$length.c[i] = df$sex[i]
} else {
df$sex.c[i] = df$sex[i]
df$length.c[i] = df$length[i]
}
}https://stackoverflow.com/questions/62708141
复制相似问题