我试图在for loop
外部定义一个空的df,然后从循环内部填充行/列,如下所示:
df<- data.frame()
for (fl in files){
dt <- read.table(fl, header = FALSE, col.names = c("year","month","value"),
colClasses = c("character","character","numeric"))
t <- aggregate(value ~ year, dt, sum)
df$year <- t$year
df$value <- t$value * someFunction()
}
现在,有多种方法可以在R中创建空df。
df <- data.frame()
# or another method
df <- data.frame(Month=character(),
Value=character(),
stringsAsFactors=FALSE)
# or another method
df <- data.frame(matrix(nrow = 0, ncol = 2))
但是当我为数据框分配值时,会产生以下错误:
df$Month <- month.abb
Error in `$<-.data.frame`(`*tmp*`, File, value = c("Jan", "Feb", "Mar", :
replacement has 12 rows, data has 0
我不知道自己在做错什么或可能会有任何误解,但我找不到解决方法。有人可以向我解释吗?
P.S:df <- data.frame(matrix(nrow = 100, ncol = 2))
可以工作,但是我不知道这是一个好主意,因为我的df的行数会有所不同。
答案 0 :(得分:2)
您需要将这些值添加到for循环中的列表中,然后可以将这些行作为数据框绑定在一起。像这样:
myList <- list()
for (m in 1:length(month.abb)) {
myList[[m]] <- month.abb[m]
}
df <- as.data.frame(do.call(rbind, myList))
答案 1 :(得分:2)
如果需要对多个输入文件执行相同的一组计算,则可以使用apply()
函数来完成此操作,而无需进行for()
循环。
为说明起见,我们将使用他发布到Kaggle的Alberto Barradas的Pokémon with stats数据库中的数据。我使用的实际CSV文件可以在PokémonData github repository上访问。
我将数据分为6个单独的CSV文件,每代神奇宝贝一个。为了使示例完全可重现,请先下载文件,然后将其存储在R Working Directory的子目录中。
我们将使用list.files()
读取文件名,这样我们就可以处理数量可变的文件,而无需手动编辑文件名,并将结果用作输入到lapply()
的文件。我们还将使用匿名函数来读取数据并执行其他计算。
lapply()
的输出是一个数据帧的列表,可以随后对其进行单独处理,或与do.call()
合并为一个数据帧,如其他答案之一所示。
download.file("https://raw.githubusercontent.com/lgreski/pokemonData/master/pokemonData.zip",
"pokemonData.zip",
method="curl",mode="wb")
unzip("pokemonData.zip")
thePokemonFiles <- list.files("./pokemonData",
full.names=TRUE)
pokemonDataFiles <- lapply(thePokemonFiles,function(x) {
y <- read.csv(x,stringsAsFactors=FALSE)
y$speedSquared <- y$Speed^2
y # return data frame to result object
})
head(pokemonDataFiles[[1]])
...以及输出:
> head(pokemonDataFiles[[1]])
Number Name Type1 Type2 Total HP Attack Defense SpecialAtk SpecialDef Speed Generation Legendary
1 1 Bulbasaur Grass Poison 318 45 49 49 65 65 45 1 False
2 2 Ivysaur Grass Poison 405 60 62 63 80 80 60 1 False
3 3 Venusaur Grass Poison 525 80 82 83 100 100 80 1 False
4 3 VenusaurMega Venusaur Grass Poison 625 80 100 123 122 120 80 1 False
5 4 Charmander Fire 309 39 52 43 60 50 65 1 False
6 5 Charmeleon Fire 405 58 64 58 80 65 80 1 False
speedSquared
1 2025
2 3600
3 6400
4 6400
5 4225
6 6400
>
披露:此代码基于我在2017年的博客文章Forms of the Extract Operator中发布的代码。
答案 2 :(得分:1)
有4种方法来发展data.frame
:
col1 <- letters[1:3] # [1] "a" "b" "c"
col2 <- letters[4:6] # [1] "d" "e" "f"
1-首先分配第一列
df1 <- data.frame(col1,stringsAsFactors = FALSE)
df1$col2 <- col2
2-首先增加列表,然后进行转换
l2 <- list()
l2$col1 <- col1
l2$col2 <- col2
df2 <- data.frame(l2,stringsAsFactors = FALSE)
3-使用以正确长度开始的列定义data.frame:
df3 <- data.frame(col1 = character(3), col2 = character(3))
df3$col1 <- col1
df3$col2 <- col2
4-定义行名称时要设置它,使其具有0列和n行
df4 <- data.frame(row.names = 1:3)
df4$col1 <- col1
df4$col2 <- col2
检查是否等同:
identical(df1,df2) # [1] TRUE
identical(df1,df3) # [1] TRUE
identical(df1,df4) # [1] TRUE
答案 3 :(得分:0)
有帮助吗?
months = c("Jan","Feb","Mar")
df <- data.frame(Month=character(),
Value=character(),
stringsAsFactors=FALSE)
for (i in 1:length(months)){
df[i,1] = months[i]
}