两周内第二次,我处理的数据包含大量空列。它的公共记录数据,我只对一个类别感兴趣。我怀疑较大数据集的其他类别使用这些列,但我关心的子集不是。所以我过滤掉了我不想要的记录,然后我想系统地剔除空列。
这个问题有一个很好的方法:
R: Remove multiple empty columns of character variables
empty_columns <- sapply(df, function (k) all(is.na(k) | k == ""))
df <- df[!empty_columns]
但是我想把它变成一个函数,所以我可以使用数据框的名称运行一次。类似的东西:
drop_empty_cols <- function(df) {
empty_columns <- sapply(df, function (k) all(is.na(k) | k == ""))
df <- df[!empty_columns]
}
drop_empty_cols(my_frame)
但是......上面的方法失败了,并且无声地失败了。这是一些示例数据:
demo <- read.table(text="Real.Val All.NA Nothin.here
1 3.5 NA tmp
2 3.0 NA tmp
3 3.2 NA tmp
4 3.1 NA tmp
5 3.6 NA tmp
6 3.9 NA tmp" , header = TRUE)
demo$Nothin.here <- ""
(我确定有一种方法可以用空列写一个可重现的例子,但是我的窒息。所以这会在你创建框架后清空它。)
如果我drop_empty_cols(demo)
我还有6 obs. of 3 variables
。如果我做
empty_columns <- sapply(demo, function (k) all(is.na(k) | k == ""))
demo <- demo[!empty_columns]
我得到了预期的结果:6 obs. of 1 variable
。但要重用,我必须三次替换demo
。甚至可以使用函数直接转换数据框吗?
答案 0 :(得分:2)
我认为你的问题几乎归结为范围之一。在R中,当您调用函数时,在该函数中创建的所有内容都是本地的,并且在该函数之外无法访问。因此,当您将演示数据帧传递给该函数时,它是在内部操作该函数,但是该函数无法访问 。为了从函数中获得结果,人们通常返回一个值并分配结果。如:
add<- function(x,y) { return(x+y)}
res <- add(1,2)
> res
[1] 3
虽然在您的具体示例中就是这种情况,但如果您确实愿意,可以在函数调用中操作演示对象。您可以使用全局赋值运算符<<-
来执行此操作,但强烈建议您使用此操作。
无论如何,我认为你有两种解决问题的方法。 1好,1坏。好的方法是在函数末尾返回操作的数据帧,然后存储。这可以通过以下方式完成:
drop_empty_cols <- function(df) {
empty_columns <- sapply(df, function (k) all(is.na(k) | k == ""))
return(df[!empty_columns])
}
res<-drop_empty_cols(demo)
str(res)
'data.frame': 6 obs. of 1 variable:
$ Real.Val: num 3.5 3 3.2 3.1 3.6 3.9
在这里,我们可以看到输出是6个观察值和1个预期的变量。
另一方面,你可以使用全局赋值运算符(我个人不喜欢它,因为事情可能会让人感到困惑,你可能会在不知不觉中覆盖结果)。此方法的代码是:
drop_empty_cols <- function(df) {
empty_columns <- sapply(df, function (k) all(is.na(k) | k == ""))
demo <<- (df[!empty_columns])
}
drop_empty_cols(demo)
str(demo)
'data.frame': 6 obs. of 1 variable:
$ Real.Val: num 3.5 3 3.2 3.1 3.6 3.9
这提供与上述方法相同的输出。但是,请注意我们实际上并不存储任何内容,我们可以简单地调用该函数来操作演示数据。此外,任何函数调用都将覆盖您的演示数据,因为它已在demo <<- (df[!empty_columns])