我有一个函数,它使用for循环遍历指定数量的列的数据帧,删除NA值,删除重复值,然后返回最终向量的长度,该向量具有指定的所有唯一值列。列表示时间,目标是显示在某个特定时间点之前存在多少总唯一值。这是样本矩阵:
X1 X2 X3 X4 X5 X6
1 F F F F F F
2 C C C C C C
3 D D D D D D
4 A# A# A# A A A
5 <NA> <NA> <NA> G G <NA>
这是功能:
uniquepitches <- function(file, col){
y <- read.csv(file, na.strings=c(""))
frame <- data.frame(y)
x <- c()
for(i in 1:col) {
noNAframe <- frame[!is.na(frame[, 1:i])]
x[i] <- length(unique(noNAframe))
}
x
}
问题在于,当我为col
的任何值运行它时,我得到了错误的值。例如,uniquepitches("testnotes.csv", 1)
为我5
提供了4
。 uniquepitches("testnotes.csv", 6)
为我[1] 5 5 5 6 6 6
提供了[1] 4 4 4 6 6 6
。现在看来,x向量在前三个贯穿期中有一个元素太多,这就是为什么长度太多了。如何修复它以使其长度正确?
答案 0 :(得分:1)
可以使用sapply()
:
df <- data.frame(X1=c('F','C','D','A#',NA), X2=c('F','C','D','A#',NA), X3=c('F','C','D','A#',NA), X4=c('F','C','D','A','G'), X5=c('F','C','D','A','G'), X6=c('F','C','D','A',NA) );
sapply(df, function(c) length(unique(c[!is.na(c)])) );
## X1 X2 X3 X4 X5 X6
## 4 4 4 5 5 4
编辑: @Molx可能是正确的,虽然OP需要澄清以确定。如果要求确实要处理累积列内容,而不是孤立地处理每个单独的列,那么您可以这样做:
sapply(1:ncol(df), function(c) length(unique(df[,1:c][!is.na(df[,1:c])])) );
## [1] 4 4 4 6 6 6
编辑:抱歉,我应该更清楚了。 sapply()
调用替换整个for循环。所以函数可以重写如下:
uniquepitches <- function(file,col) {
frame <- read.csv(file,na.strings=c(""));
sapply(1:col, function(c) length(unique(frame[,1:c][!is.na(frame[,1:c])])) );
}
(另请注意,read.csv()
会返回data.frame,因此无需手动强制。)