【问题标题】:Data from multiple variables in a single column, how to fix?- R dataframe来自单个列中多个变量的数据,如何修复?- R 数据框
【发布时间】:2016-04-15 15:45:41
【问题描述】:

我收到了几百个 Excel 文件,其中的数据以“风格化”格式存储。当我将文件批量转换为 .csv 并读取相关行时,单个文件中的数据如下所示:

 data.frame(x1= c("year", "2014", "site", "28",NA,NA), x2= LETTERS[1:6])
    x1 x2
1 year  A
2 2014  B
3 site  C
4   28  D
5 <NA>  E
6 <NA>  F

我希望它看起来像这样:

data.frame(year= rep("2014",6), site= rep("28",6), x2= LETTERS[1:6])
  year site x2
1 2014   28  A
2 2014   28  B
3 2014   28  C
4 2014   28  D
5 2014   28  E
6 2014   28  F

如您所见,有 2 个变量名称(年份和地点)及其数据(“2014”和“28”)存储在单个列中。 (变量数据始终位于变量名称后面的行中。)数据框中的其他变量,在本例中为 x2,格式正确。

我能否就如何有效地将这些变量放入自己的列中提出一些建议?在rbind-ing 进入 1 之前,我需要将解决方案应用于大约 100 个不同长度的数据帧。

【问题讨论】:

    标签: r dataframe tidyr


    【解决方案1】:

    在基础 R 中:

        df <- data.frame(x1= c("year", "2014", "site", "28",NA,NA), x2= LETTERS[1:6], stringsAsFactors = FALSE)
    

    制作几个索引:

    year_idx <- which(df$x1 == "year")
    site_idx <- which(df$x1 == "site")
    

    获取它们的值,

    year <- df$x1[year_idx +1]
    site <- df$x1[site_idx +1]
    

    使用新值创建新列:

    df["year"] <- year
    df["site"] <- site
    

    重新排列:

    df <- df[, c(3,4,2)]
    
    stylized_rearranger <- function(df) {
    and just do the above steps within and return
    df
    }
    

    【讨论】:

    • 更简单,df$year&lt;- df$x1[which(df$x1=="year")+1]df$site&lt;- df$x1[which(df$x1=="site")+1]
    • 确实,链式表示法总是让我感到惊讶,但我发现从简单开始很有帮助;然后是链接,一旦我理解了其中的含义。
    【解决方案2】:

    只要文件之间的格式一致(如果),您可以编写代码来清理一个文件,将其放入一个函数中,然后使用 `lapply(files, myFunction) 将所有文件读入为一个列表。在您的示例中,为方便起见,命名为 df:

    # code to clean data
    newdf <- data.frame("year"=df$x1[2], "site"=df$x1[4], "x2"=df$x2)
    
    # wrap this in a function together with read.csv
    myFunction <- function(infile) {
      df <- read.csv(infile, as.is=T)
      newdf <- data.frame("year"=df$x1[2], "site"=df$x1[4], "x2"=df$x2)
      return(newdf)
    }
    

    然后使用lapply

    fileList <-list.files(<path>)
    # new df names, remove .csv or .xlsx extensions, you may need to do a bit more
    dfNames <- gsub("\\..*$", "", fileList)
    # get a list of the data.frames
    dataList <- lapply(fileList, myFunction)
    

    【讨论】:

    • 谢谢,这在我的情况下有效,但@Chris 的答案只是通过利用行的固定顺序并使用它们的相对索引而不是依赖于它们的绝对索引来更通用一点
    • 这是我用于循环创建单个数据帧的代码:files &lt;- list.files(pattern="*.csv")do.call(rbind, lapply(files, myFunction))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-22
    • 2021-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-23
    相关资源
    最近更新 更多