在过滤R

时间:2018-04-24 18:55:48

标签: r function dataframe subset rbind

我有几个数据集(“001.csv”,“002.csv”,依此类推,直到332)存储在同一个文件夹中,具有以下结构(示例):

id  p1    p2    
2   35.0  na    
2   5.00  2.05  
2   0.35  1.56  
2   na    0.79 
2   5.23  0.13
2   5.01  0.03

我需要创建一个能够读取一个或多个文件的函数,并向我回复“p1”和“p2”都有一个给定值(即没有NA)的情况,我为此写了这个:

cc <- function(directory, id=1:332) {
    files_list <- list.files(directory, full.names = TRUE)
    for (i in id) {
            dat <- read.csv(files_list[i])
    }
    nobs <- length(which(!is.na(dat$p1) & !is.na(dat$p2)))
    completecases <- data.frame(id, nobs)
    completecases
    }

如果我为“id”选择单个值,这可以完美地工作;在这种情况下,结果将是这样的:

> cc(directory, 1)
    id nobs
    1  3

但是,如果我想知道多个文件中的观察数量,它会为每个“id”返回最高值“id”的观察数量。例如,

> cc(directory, 1:2)
    id nobs
    1  4
    2  4

而不是:

> cc(directory, 1:2)
    id nobs
    1  3
    2  4

我认为我需要通过“id”对我的数据进行子集化,或者为每个“id”使用“rbind”,但到目前为止我还没有找到正确的公式。 有谁知道如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

尝试这样的事情

我编辑你的函数来处理单个文件,并在用NA过滤 out 行后返回行数

count_nobs <- function(fi) {
    require(dplyr)
    dat <- read.csv(fi)
    dat[complete.cases(dat), ] %>% count()
}

使用purrr:map_dfr调用函数,该函数遍历files_list并对结果进行rbinds

library(tidyverse)
files_list <- list.files(directory, full.names=TRUE)
result <- map_dfr(files_list, ~count_nobs(.x), .id="id")

答案 1 :(得分:0)

它不起作用的原因是我应该在for循环中包含“nobs”,例如:

cc <- function(directory, id=1:332) {
files_list <- list.files(directory, full.names = TRUE)
nobs <- c()
for (i in id) {
        dat <- read.csv(files_list[i])
        nobs <- c(nobs, length(which(!is.na(dat$p1) & !is.na(dat$p2))))
}
completecases <- data.frame(id, nobs)
completecases
}

不考虑它,“nobs”总是占据dat中“id”的最后一个值。