我使用以下命令将一个大数据文件读入R中
data <- as.data.set(spss.system.file(paste(path, file, sep = '/')))
数据集包含不应该属于的列,并且只包含空白。这个问题与R基于附加到SPSS文件(源)的变量标签创建新变量有关。
不幸的是,我还不能确定解决这个问题的必要选项。我已经尝试了所有的:foreign::read。spss memisc: spss.system。和Hemisc::spss。Get, with no luck.
相反,我想读取整个数据集(带有幽灵列)并手动删除不必要的变量。由于幽灵列只包含空格,我想从我的数据中删除任何变量。表中唯一观测值的个数等于1。
我的数据很大,所以存储在data中。表的格式。我想确定一种简单的方法来检查每列中唯一观测值的数量,并删除只包含一个唯一观测值的列。
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))
但是,我希望计算大型数据文件的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
在我看来问题在于
dt[, 'a', with = F]
返回一个data.table类的对象。这个对象的长度为1是有意义的,因为它是一个数据。表中包含1个变量。我们知道data.frames其实就是变量列表,所以在这个例子中,列表的长度就是1。
下面是我将如何补救的伪代码,使用data.frame的方式:
for (x in names(data)) {
unique.obs <- length(unique(data[, x]))
if (unique.obs == 1) {
data[, x] <- NULL
}
}
关于如何更有效地查询数据中按列的唯一观察值的数量的任何见解。非常感谢您的餐桌。或者,如果数据中只有一个唯一的观测值,您可以建议如何删除观测值。
更新:uniqueN
从1.9.6版本开始,该解决方案有一个内置(优化)版本,uniqueN
函数。现在就像这样简单:
dt[ , lapply(.SD, uniqueN)]
如果想要查找每列中唯一值的数量,可以使用
dt[, lapply(.SD, function(x) length(unique(x)))]
## a b c
## 1: 10 10 1
要使您的功能工作,您需要在[.data.table
中使用with=FALSE
,或者简单地使用[[
代替(阅读fortune(312)
…)
lapply(names(df) function(x) length(unique(dt[, x, with = FALSE])))
或
lapply(names(df) function(x) length(unique(dt[[x]])))
工作一步走
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]
其他答案中的方法都很好。另一种添加方法,只是为了好玩:
for (i in names(DT)) if (length(unique(DT[[i]]))==1) DT[,(i):=NULL]
或者如果有重复的列名:
for (i in ncol(DT):1) if (length(unique(DT[[i]]))==1) DT[,(i):=NULL]
NB: (i)
在:=
的LHS上是一个技巧,使用i
的值而不是名为"i"
的列。
这是你的核心问题的解决方案(我希望我是对的)。
require(data.table)
### Create a data.table
dt <- data.table(a = 1:10,
b = letters[1:10],
d1 = "",
c = rep(1, times = 10),
d2 = "")
dt
a b d1 c d2
1: 1 a 1
2: 2 b 1
3: 3 c 1
4: 4 d 1
5: 5 e 1
6: 6 f 1
7: 7 g 1
8: 8 h 1
9: 9 i 1
10: 10 j 1
首先,我引入两个没有任何值的列d1
和d2
。那些你想删除的,对吧?如果是这样,我就识别这些列并选择dt
中的所有其他列。
only_space <- function(x) {
length(unique(x))==1 && x[1]==""
}
bolCols <- apply(dt, 2, only_space)
dt[, (1:ncol(dt))[!bolCols], with=FALSE]
不知怎么的,我觉得你可以进一步简化它…
输出: a b c
1: 1 a 1
2: 2 b 1
3: 3 c 1
4: 4 d 1
5: 5 e 1
6: 6 f 1
7: 7 g 1
8: 8 h 1
9: 9 i 1
10: 10 j 1
有一种简单的方法可以使用"dplyr"库,然后使用select函数,如下所示:
库(dplyr)
newdata <- select(old_data,第一个变量,第二个变量)
注意,你可以选择任意多的变量。
你将得到你想要的数据类型。
许多谢谢,Fadhah