如何在 [r] 中缺少值的数据中使用多个关系运算符为新变量赋值?



我有一个包含 20 个变量的数据集,还有相当多的缺失数据。 我正在尝试添加一个新变量,并根据另一个变量的值为每一行分配一个值。 下面是代码和一个较小的数据集,它给出了与我的较大数据集相同的错误。 有什么建议吗?

A=seq(1,6); B=seq(2,4)
length(A)=7; length(B)=7
m=cbind(A,B)

我不完全了解从矩阵转换为数据帧的作用。

df=as.data.frame(m)
df

首先尝试创建一个分类变量,在赋值新变量时使用

df$Acat=cut(df$A,
breaks=c(-Inf,2.5,4.5,Inf),
labels=c("low","mod","hi"))
df$Acat

下面的代码是我得到错误的地方":参数长度为零">

if (df$Acat.=="low"){
df$C=1
}else if (df$Acat.=="mod"){
df$C=2
}else if(df$Acat.=="hi"){
df$C=3
}else {
df$C=NA
}
df$C

我也尝试过这种方式,使用数字变量来分配新变量的值,但我收到此错误:

条件的长度> 1,并且仅使用第一个元素

if (df$A<2.5){
df$D=1
} else if (df$A>=2.5 && df$A<4.5){
df$D=2
} else if (df$A>=4.5){
df$D=3
} else {
df$D=NA
}
df$D

这里有一些提示。在 R 中,通常使用<-运算符将变量分配给名称。公平地说,我甚至不知道你可以为变量分配长度,所以我学到了一些新东西。

A <- seq(1, 6)
length(A) <- 7
B <- seq(2, 4)
length(B) <- 7
m <- cbind(A, B)

matrixdata.frame之间的区别在于,矩阵是数字向量,其dim属性指定维度(数组也是如此(,而 data.frame 是一系列长度相等的列表(沿列((行数(。

这在实践中意味着data.frame可以在不同的列中有任何内容,例如,一个可能是character,另一个可能是integer,而矩阵只能包含相同类型的数据。

> attributes(m)
$dim
[1] 7 2
$dimnames
$dimnames[[1]]
NULL
$dimnames[[2]]
[1] "A" "B"
> df <- as.data.frame(m)
> attributes(df)
$names
[1] "A" "B"
$class
[1] "data.frame"
$row.names
[1] 1 2 3 4 5 6 7
> is.list(m)
[1] FALSE
> is.list(df)
[1] TRUE

您用于尝试为列赋值的 if-else 语句不起作用,因为它们不是矢量化的:它们需要单个TRUEFALSE,而不是逻辑向量。您可以通过计算表达式来查看表达式比 1 长,并询问长度:

> df$Acat == "low"
[1]  TRUE  TRUE FALSE FALSE FALSE FALSE    NA
> length(df$Acat == "low")
[1] 7

相反,您可以使用所需的值构建命名向量,并使用子集操作将它们移动到正确的位置:

df$Acat <- cut(df$A,
breaks=c(-Inf,2.5,4.5,Inf),
labels=c("low","mod","hi"))
named_vec <- c("low" = 1, "mod" = 2, "hi" = 3)
df$C <- named_vec[df$Acat]

这给了你这个数据帧:

> df
A  B Acat  C
1  1  2  low  1
2  2  3  low  1
3  3  4  mod  2
4  4 NA  mod  2
5  5 NA   hi  3
6  6 NA   hi  3
7 NA NA <NA> NA

有多种其他选项可以获得相同的结果,但我认为按名称进行子集是相对直观的。

你似乎是R的新手。随着你的继续,你会发现,在R中,有些事情的完成方式与其他语言完全不同。

例如,要根据您的条件设置列C,您需要执行以下操作:

df$C = ifelse(
df$Acat=="low", 1, ifelse(
df$Acat=="mod", 2, ifelse(
df$Acat=="hi", 3, NA 
)))

如果您正在使用 tidyverse,您也可以使用 case_when。

最新更新