And*_*eas 7 r unique variable-length data.table
我使用以下命令将大数据文件读入R中
data <- as.data.set(spss.system.file(paste(path, file, sep = '/')))
Run Code Online (Sandbox Code Playgroud)
数据集包含不属于的列,并且只包含空格.此问题与R根据附加到SPSS文件(源)的变量标签创建新变量有关.
不幸的是,我无法确定解决问题所需的选项.我已经尝试了所有:foreign :: read.spss,memisc:spss.system.file和Hemisc :: spss.get,没有运气.
相反,我想读取整个数据集(使用ghost列)并手动删除不必要的变量.由于ghost列只包含空格,我想从我的data.table中删除任何变量,其中唯一观察的数量等于1.
我的数据很大,因此它们以data.table格式存储.我想确定一种简单的方法来检查每列中唯一观察的数量,并删除仅包含一个唯一观察的列.
require(data.table)
### Create a data.table
dt <- data.table(a = 1:10,
b = letters[1:10],
c = rep(1, times = 10))
### Create a comparable data.frame
df <- data.frame(dt)
### Expected result
unique(dt$a)
### Expected result
length(unique(dt$a))
Run Code Online (Sandbox Code Playgroud)
但是,我希望计算大型数据文件的obs数,因此不希望按名称引用每一列.我不是eval(parse())的粉丝.
### I want to determine the number of unique obs in
# each variable, for a large list of vars
lapply(names(df), function(x) {
length(unique(df[, x]))
})
### Unexpected result
length(unique(dt[, 'a', with = F])) # Returns 1
Run Code Online (Sandbox Code Playgroud)
在我看来问题是这样的
dt[, 'a', with = F]
Run Code Online (Sandbox Code Playgroud)
返回类"data.table"的对象.这个对象的长度是1是有道理的,因为它是一个包含1个变量的data.table.我们知道data.frames实际上只是变量列表,所以在这种情况下,列表的长度只有1.
这是使用data.frame方式解决方案的伪代码:
for (x in names(data)) {
unique.obs <- length(unique(data[, x]))
if (unique.obs == 1) {
data[, x] <- NULL
}
}
Run Code Online (Sandbox Code Playgroud)
关于如何更有效地询问data.table中列的独特观察数量的任何见解将非常感激.或者,如果您可以建议如果在数据中只有一个独特的观察结果,那么如何删除观察结果.表格会更好.
uniqueN从版本1.9.6开始,该解决方案的内置(优化)版本就是该uniqueN功能.现在这很简单:
dt[ , lapply(.SD, uniqueN)]
Run Code Online (Sandbox Code Playgroud)
如果要在每列中找到唯一值的数量,例如
dt[, lapply(.SD, function(x) length(unique(x)))]
## a b c
## 1: 10 10 1
Run Code Online (Sandbox Code Playgroud)
要使你的功能工作,你需要在with=FALSE内部使用[.data.table,或者只是[[改为使用(也读fortune(312)......)
lapply(names(df) function(x) length(unique(dt[, x, with = FALSE])))
Run Code Online (Sandbox Code Playgroud)
要么
lapply(names(df) function(x) length(unique(dt[[x]])))
Run Code Online (Sandbox Code Playgroud)
将工作
一步到位
dt[,names(dt) := lapply(.SD, function(x) if(length(unique(x)) ==1) {return(NULL)} else{return(x)})]
# or to avoid calling `.SD`
dt[, Filter(names(dt), f = function(x) length(unique(dt[[x]]))==1) := NULL]
Run Code Online (Sandbox Code Playgroud)