R:使用不存在的变量进行子集不会产生错误

时间:2018-02-05 19:01:30

标签: r if-statement brackets

在创建主要变量时,我不小心省略了将数据分组的主变量。我使用括号来插入NA,并且没有报告错误。为了检查我的理智,我对ifelse做了同样的事情并且R创建了一条错误消息。我担心的是,如果不仔细审查,并且有些运气,我可能永远不会知道我的错误。

其他人如何以不同的方式编码,以便在将来减少这种可能性(以最小的时间成本)?还有,我应该注意其他类似的问题吗?谢谢,可重现的例子如下。

dt <- data.frame(
group_name = c("D44", "D44","D44", "D45", "D45", "D47", "D47", "D47", "D47", "D48"),
order_number = sample(1:10))

dt$group_name <- as.character(dt$group_name) # so not a factor

dt <- dt[order(dt$group_name, dt$order_number),] # sort data

dt$lead1order_number <- c(dt$order_number[-1], NA)

# COMMENT OUT NEXT LINE AND RUN, no error with brackets, but one with ifelse
dt$lead1group_name <- c(dt$group_name[-1], NA) 

# done two different ways below
    # if group_name doesn't match lead1group_name, then lead1order_number NA
dt$lead1order_number[dt$group_name != dt$lead1group_name] <- NA  

dt$lead1order_number <- ifelse(dt$group_name != dt$lead1group_name, NA, dt$lead1order_number)

1 个答案:

答案 0 :(得分:1)

你的问题很深。括号(也称为子集)的问题是R的关键特征之一。很难以全面的方式回答您的问题。我只想提出一个可能最简单的解决方案:

# `stringsAsFactors = FALSE` ensures that strings will not be transformed to factors
dt <- data.frame(group_name = c("D44", "D44","D44", "D45", 
    "D45", "D47", "D47", "D47", "D47", "D48"),
    order_number = sample(1:10), stringsAsFactors = FALSE)
dt <- dt[order(dt$group_name, dt$order_number),] # sort data
dt$lead1order_number <- c(dt$order_number[-1], NA)
# the example was slightly modified to demonstrate subsetting with NA
dt$lead1group_name <- c(dt$group_name[-c(1:2)], NA, "D")

我们假设,我们需要一个"lead2group_name"列,这在我们的数据框中是遗漏的。我建议使用的关键问题是不同的子集方法给出了不同的结果:

使用$[[简化子集将不会产生任何结果:

print(dt$lead2group_name)
> NULL
使用[

保留子集会导致错误:

print(dt[ ,"lead2group_name", drop = FALSE])
  

[.data.frame(dt ,,“lead2group_name”)中的错误:未定义的列   选择

我会使用此问题来确保data.frame中存在请求的列:

ind_of_non_match <- which(dt[ ,"group_name", drop = FALSE] != dt[ ,"lead1group_name", drop = FALSE])
ind_of_na <- which(is.na(dt[ , "lead1group_name", drop = FALSE]))
dt$lead1order_number[c(ind_of_non_match, ind_of_na)] <- NA

请注意,这是一步一步的方法

dt$lead1order_number[(dt[ ,"group_name", drop = FALSE] != dt[ ,"lead1group_name", drop = FALSE])] <- NA

默默地忽略NA的{​​{1}}值。这似乎不是最安全的方式。这就是为什么我宁愿使用"lead1group_name"which()"lead1group_name"的不匹配与group_nameNA的存在分开。

希望,这对你目前的工作有用。至于与使用子集和分配相关的一般问题,您可能会发现使用R教程查看"lead1group_name" R帮助以及更详细地研究子集化方法非常有用。