我正在R中处理多个大数据框架,并且试图编写可以修改每个框架的函数(给定一组通用参数)。一种功能给我带来麻烦(如下所示)。
RawData <- function(x)
{
for(i in 1:nrow(x))
{
if(grep(".DERIVED", x[i,]) >= 1)
{
x <- x[-i,]
}
}
for(i in 1:ncol(x))
{
if(is.numeric(x[,i]) != TRUE)
{
x <- x[,-i]
}
}
return(x)
}
此函数的目的是双重的:首先,删除任何在其单元格中包含“ .DERIVED”字符串的行(使用grep);其次,删除所有非数字列(使用是数字)。在以下情况下出现错误:
if(grep(".DERIVED", x[i,]) >= 1)
该错误指出“参数长度为零”,我认为通常与向量中的NULL值相关联。但是,我在整个数据帧上使用了is.null,这给了我错误,并且它确认DF中没有空值。我确定我在这里缺少相对简单的东西。任何建议将不胜感激。
答案 0 :(得分:1)
如果可以使用非base-R功能,则应该可以解决您的问题。 df
是此处讨论的data.frame
。它也比遍历行要快(如果可以避免,通常不建议这样做)。
library(dplyr)
library(stringr)
df %>%
filter_all(!str_detect(., '\\.DERIVED')) %>%
select_if(is.numeric)
您可以像其他任何操作一样使它成为函数:
mattsFunction <- function(dat){
dat %>%
filter_all(!str_detect(., '\\.DERIVED')) %>%
select_if(is.numeric)
}
您可能应该给它起个更好的名字
答案 1 :(得分:0)
错误出在行上
if(grep(".DERIVED", x[i,]) >= 1)
当grep找不到术语“ .DERIVED”时,它将返回零长度的内容,您的不等式不会返回TRUE或FALSE,而是返回logical(0)
。该错误告诉您if
语句无法评估logical(0) >= 1
一个简单的例子:
if(grep(".DERIVED", "1234.DERIVEDabcdefg") >= 1) {print("it works")} # Works nicely, since the inequality can be evaluated
if(grep(".DERIVED", "1234abcdefg") > 1) {print("no dice")}
您可以将该行替换为if(length(grep(".DERIVED", x[i,])) != 0)
您还没有注意到其他事情,那就是您要删除循环中的行/列。假设您删除第5列,则下一个循环迭代(当i = 6时)将处理是第7行! (这将导致错误Error in
[。data.frame (x, , i) : undefined columns selected
的结束)
答案 2 :(得分:0)
我更喜欢使用dplyr,但是如果您需要使用基本R函数,则可以使用一些没有if语句的方法来实现。
请注意,您应该考虑使用"\\.DERIVED"
而不是".DERIVED"
的正则表达式版本,这意味着“任何字符后跟DERIVED”。
我没有示例数据或输出,所以这是我最好的选择...
# Made up data
test <- data.frame(a = c("data","data.DERIVED","data","data","data.DERIVED"),
b = (c(1,2,3,4,5)),
c = c("A","B","C","D","E"),
d = c(2,5,6,8,9),
stringsAsFactors = FALSE)
# Note: The following code assumes that the column class is numeric because the
# example code provided assumed that the column class was numeric. This will not
# detects if the column is full of a string of character values of only numbers.
# Using the base subset command
test2 <- subset(test,
subset = !grepl("\\.DERIVED",test$a),
select = sapply(test,is.numeric))
# > test2
# b d
# 1 1 2
# 3 3 6
# 4 4 8
# Trying to use []. Note: If only 1 column is numeric this will return a vector
# instead of a data.frame
test2 <- test[!grepl("\\.DERIVED",test$a),]
test2 <- test2[,sapply(test,is.numeric)]
# > test2
# b d
# 1 1 2
# 3 3 6
# 4 4 8