【问题标题】:R making a list of dataframesR制作数据框列表
【发布时间】:2020-03-22 14:21:36
【问题描述】:

我有一个相当大的数据框,我正在使用 slice() 将其切成我需要的部分。我尝试编写一个我认为可以完成我想做的事情的函数。 这就是我最初做事的方式:

Alabama <- slice(Crime_US, 1:31)

Alaska <- slice(Crime_US, 40:70)

Arizona <- slice(Crime_US, 79:109)

Arkansas <- slice(Crime_US, 118:148)

California <- slice(Crime_US, 156:186)

以下是阿拉巴马州的一些输出:

Year  Population `Violent crime to… `Murder and nonneglige… `Legacy rape /1` `Revised rape /… Robbery `Aggravated assa…
  <chr> <chr>      <chr>              <chr>                   <chr>            <chr>            <chr>   <chr>            
1 1970  3444165    10185              404                     637              NA               1731    7413             
2 1971  3479000    10835              524                     661              NA               2005    7645             
3 1972  3510000    10994              496                     660              NA               2407    7431             
4 1973  3539000    12390              468                     751              NA               2809    8362             
5 1974  3577000    13338              536                     811              NA               3562    8429             
6 1975  3614000    14201              577                     738              NA               4446    8440

这就是我想要的方式。这里有一些代码需要澄清。

Crime_US <- read_excel("crimeAllStates.xlsx", skip=9)

states_vec <- c("Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "D.C.", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennslyvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming")


counter <- 1
m <- 1
n <- 31
makeMyStates <- function(df) {
  states_vec[counter] <- slice(df, m:n)
  counter <- (counter + 1)
  m <- (m + 39)
  n <- (n + 39)
}

sapply(Crime_US, makeMyStates)

不幸的是,我收到了这个错误:

Error in UseMethod("slice_") : no applicable method for 'slice_' applied to an object of class "character"

我尝试用谷歌搜索错误无济于事,而且我对 R 没有太多经验。

【问题讨论】:

  • split(Crime_US, rep(states_vec, each = 31))
  • 我真的很想用这个,不幸的是数据框在状态之间有 9 个空白行,所以看起来只有第一个小标题是正确的。不过谢谢你
  • split(Crime_US[!is.na(Crime_US$Year), ], rep(states_vec, each = 31))
  • 哦,伙计,我真的很喜欢您的解决方案,我希望我知道自己做错了什么,但这对我不起作用。不过感谢您的帮助。

标签: r function slice


【解决方案1】:

如果您必须根据mn 中的值采取任意中断,我认为尝试填充列表可能会有所帮助。

您的行:states_vec[counter] &lt;- slice(df, m:n) 正在尝试使用数据框填充字符向量,这就是您收到此错误的原因。

带有列表的 for 循环可能是解决此问题的一种方法(尽管它不是很整洁):

    state_crime <- list() 
    m <- 1
    n <- 31

    for (i in 1:length(states_vec)){

      state_crime[[i]] <- slice(Crime_US, m:n) %>%
                          mutate(state = states_vec[i])

      m <- (m + 39)
      n <- (n + 39) 

      }

然后使用states_vec 列表命名列表中的每个元素,或者只是绑定行以创建一个新的数据框。

names(state_crime) &lt;- states_vec

bind_rows(state_crime)

【讨论】:

  • 虽然这不是一种非常简洁的方式,但它很聪明,并且通过另外一段代码满足了我的需求:list2env(state_crime,.GlobalEnv)。非常感谢您的帮助。
【解决方案2】:

如果要创建 39 行的组,并且没有其他方法来识别每个状态,我们可以创建一个索引序列并使用 Map 对其进行子集化

m <- 1
n <- 31
no_rows <- nrow(Crime_US)

Map(function(x, y) Crime_US[x:y, ], seq(m,no_rows, 39), seq(n,no_rows, 39))

tidyverse 方式是

library(purrr)
library(dplyr)

map2(seq(m,no_rows, 39), seq(n,no_rows, 39), ~slice(df, .x:.y))

【讨论】:

  • 我喜欢它的优雅,不幸的是它抛出了一个错误,而且小标题也没有像我需要的那样分配给状态名称。
  • @JayWehrman 所以没有一种模式可以让您正确识别一个状态结束和其他状态的开始?
  • 不幸的是,我拥有的最好的是:我知道第一个状态的信息从第 1 行开始,到第 31 行结束,然后跳过 9 行,下一个状态从第 40 行开始,到第 70 行结束, 跳过 9 并继续这种模式。
  • @JayWehrman 因为,我没有你的完整数据,我不知道特定状态何时开始或结束。它基于您提供的信息。我的解决方案基于索引创建数据子集。在控制台中运行它并确保这些是每个状态的开始索引seq(m,no_rows, 39),这些是结束索引seq(n,no_rows, 39)
猜你喜欢
  • 1970-01-01
  • 2018-08-01
  • 1970-01-01
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-04
相关资源
最近更新 更多