在 R 中创建新变量 - 缺少数据的问题
Creating New Variables in R- issues with missing data
我的 R 代码一直遇到基于另一个变量生成新变量的问题。每个参与者都有多个不同变量的条目。并非所有这些变量对每个参与者都很重要。我有一个虚拟编码变量,用于告诉我在生成新变量时应该使用哪个变量。这是我的数据的样子。
data
id use v1 v2 v3
1 1 2 2 1
2 2 NA 1 2
3 3 1 NA 3
4 1 3 5 NA
5 2 4 4 1
我将尝试使用虚拟编码变量创建一个新变量。对于这个例子,is use is 1,我想对 x 使用 v1 的值。如果 use 是 2,那么我想对 x 使用 v2。如果 use 是 3,我想对 x 使用 v3。这是我使用的代码。
data$x [data$use == 1] <- data$v1
data$x [data$use == 2] <- data$v2
data$x [data$use == 3] <- data$v3
当我尝试 运行 代码时,我会收到错误消息“要替换的项目数不是替换长度的倍数”。
我做了一些研究,我认为这与数据丢失有关(尽管我可能是错的)。我尝试在 [] 中使用 is.na () 但这并不能解决问题。
我以前用ifelse解决过类似的问题,但我认为代码在这种情况下不会起作用,因为我有两种以上的情况(我不确定ifelse是否是累积的)。
为什么会出现此错误,解决此问题的最佳方法是什么?
您可以试试下面的代码
v <- c("v1", "v2", "v3")
list2env(
setNames(
lapply(v, function(x) data[[x]][data$use == gsub("\D", "", x)]),
v
),
envir = .GlobalEnv
)
您可以通过
查看
> mget(ls(pattern = "v\d+"))
$v1
[1] 2 3
$v2
[1] 1 4
$v3
[1] 3
您的问题是 <-
作业的左右两侧长度不同。
## data$x[data$use == 1] <- data$v1
data$x[data$use == 1]
#[1] 2 3
data$v1
#[1] 2 NA 1 3 4
如果你通过选择两边来匹配它们,你在笑:
data$x[data$use == 1] <- data$v1[data$use == 1]
data$x[data$use == 2] <- data$v2[data$use == 2]
data$x[data$use == 3] <- data$v3[data$use == 3]
# id use v1 v2 v3 x
#1 1 1 2 2 1 2
#2 2 2 NA 1 2 1
#3 3 3 1 NA 3 3
#4 4 1 3 5 NA 3
#5 5 2 4 4 1 4
您可以避免需要编写多行代码,并使用矩阵索引使它适用于任意数量的变量,但是,根据我之前的回答:
data[c("v1","v2","v3")][cbind(seq_len(nrow(data)), data$use)]
#[1] 2 1 3 3 4
这实质上是使用带有行和列索引的 matrix
从 v1-3
变量中获取正确的值:
cbind(seq_len(nrow(data)), data$use)
## row col
# [,1] [,2]
#[1,] 1 1
#[2,] 2 2
#[3,] 3 3
#[4,] 4 1
#[5,] 5 2
## assign it get the same result obviously:
data$x <- data[c("v1","v2","v3")][cbind(seq_len(nrow(data)), data$use)]
我的 R 代码一直遇到基于另一个变量生成新变量的问题。每个参与者都有多个不同变量的条目。并非所有这些变量对每个参与者都很重要。我有一个虚拟编码变量,用于告诉我在生成新变量时应该使用哪个变量。这是我的数据的样子。
data
id use v1 v2 v3
1 1 2 2 1
2 2 NA 1 2
3 3 1 NA 3
4 1 3 5 NA
5 2 4 4 1
我将尝试使用虚拟编码变量创建一个新变量。对于这个例子,is use is 1,我想对 x 使用 v1 的值。如果 use 是 2,那么我想对 x 使用 v2。如果 use 是 3,我想对 x 使用 v3。这是我使用的代码。
data$x [data$use == 1] <- data$v1
data$x [data$use == 2] <- data$v2
data$x [data$use == 3] <- data$v3
当我尝试 运行 代码时,我会收到错误消息“要替换的项目数不是替换长度的倍数”。
我做了一些研究,我认为这与数据丢失有关(尽管我可能是错的)。我尝试在 [] 中使用 is.na () 但这并不能解决问题。
我以前用ifelse解决过类似的问题,但我认为代码在这种情况下不会起作用,因为我有两种以上的情况(我不确定ifelse是否是累积的)。
为什么会出现此错误,解决此问题的最佳方法是什么?
您可以试试下面的代码
v <- c("v1", "v2", "v3")
list2env(
setNames(
lapply(v, function(x) data[[x]][data$use == gsub("\D", "", x)]),
v
),
envir = .GlobalEnv
)
您可以通过
查看> mget(ls(pattern = "v\d+"))
$v1
[1] 2 3
$v2
[1] 1 4
$v3
[1] 3
您的问题是 <-
作业的左右两侧长度不同。
## data$x[data$use == 1] <- data$v1
data$x[data$use == 1]
#[1] 2 3
data$v1
#[1] 2 NA 1 3 4
如果你通过选择两边来匹配它们,你在笑:
data$x[data$use == 1] <- data$v1[data$use == 1]
data$x[data$use == 2] <- data$v2[data$use == 2]
data$x[data$use == 3] <- data$v3[data$use == 3]
# id use v1 v2 v3 x
#1 1 1 2 2 1 2
#2 2 2 NA 1 2 1
#3 3 3 1 NA 3 3
#4 4 1 3 5 NA 3
#5 5 2 4 4 1 4
您可以避免需要编写多行代码,并使用矩阵索引使它适用于任意数量的变量,但是,根据我之前的回答:
data[c("v1","v2","v3")][cbind(seq_len(nrow(data)), data$use)]
#[1] 2 1 3 3 4
这实质上是使用带有行和列索引的 matrix
从 v1-3
变量中获取正确的值:
cbind(seq_len(nrow(data)), data$use)
## row col
# [,1] [,2]
#[1,] 1 1
#[2,] 2 2
#[3,] 3 3
#[4,] 4 1
#[5,] 5 2
## assign it get the same result obviously:
data$x <- data[c("v1","v2","v3")][cbind(seq_len(nrow(data)), data$use)]