我正在尝试编写某种循环函数,这将允许我将相同的代码集应用于存储在一个列表中的数十个数据帧。每个数据帧具有相同数量的列和每列相同的标题,但行数在数据帧中有所不同。
这些数据来自以自我为中心的社交网络研究,我从边缘列表格式收集了来自数十个不同受访者的自我网络数据。我使用的数据收集软件将每次访谈的数据存储在自己的.csv文件中。以下是特定数据框(image of raw data)的原始数据的图像。
出于我的目的,我只需要使用第四,第六和第七列中的数据。此外,我只需要数据行,其中最后一列的值为4,此时可以完全删除最后一列。最终结果是一个两列数据框,表示人群之间的关系。
读入数据并将其存储为对象后,我运行了以下代码:
x100291 = `100291AlterPair.csv` #new object based on raw data
foc.altername = x100291$Alter.1.Name
altername = x100291$Alter.2.Name
tievalue = x100291$AlterPair_B
tie = tievalue
tie[(tie<4)] = NA
egonet.name = data.frame(foc.altername, altername, tievalue)
depleted.name = cbind(tie,egonet.name)
depleted.name = depleted.name[is.na(depleted.name[,1]) == F,]
dep.ego.name = data.frame(depleted.name$foc.altername, depleted.name$altername)
这产生了以下数据框(image of final data)。这最终是我想要的。
现在我知道我可以将同一组代码剪切并粘贴100次以上并手动更改文件名,但我不想这样做。相反,我将所有原始.csv文件作为数据框存储在一个列表中。我怀疑我可以使用apply
命令之一在所有数据帧中应用相同的代码,但我无法弄清楚。
有没有人对如何将此基本代码应用于数据框列表有任何建议,以便最终得到一个包含清理和缩减版数据的新列表?
非常感谢!
答案 0 :(得分:0)
逻辑可以简化。尝试创建自定义函数并应用于所有数据框。
cleanDF <- function(mydf) {
if( all(!c('AlterPair_B', 'Alter.1.Name', 'Alter.2.Name') %in%
names(mydf))) stop("Check data frame names")
condition <- mydf[, 'AlterPair_B'] >= 4
mydf[condition, c("Alter.1.Name", "Alter.2.Name")]
}
big_list <- lapply(all_my_files, read.csv) #read in all data frames
result <- do.call('rbind', lapply(big_list, cleanDF))
自定义函数cleanDF
首先检查所有相关列名是否存在。然后它定义4个或更多的条件AlterPair_B&#39;。最后,按该条件对两个目标列进行子集化。我使用了名为&#39; big_list&#39;代表所有数据帧。
答案 1 :(得分:0)
您没有提供可重复的示例,因此很难解决您的问题。但是,我不希望你的问题无法回答。确实,使用lapply
将是一个快速解决方案,通常优于loop
。但是,既然你提到自己是初学者,那么这里有一个loop
如何做到这一点,这更容易理解。
您需要将所有csv文件放在一个没有其他内容的文件夹中。然后,您阅读文件名并将其放入list
。使用NULL
初始化空结果对象。然后,您可以在loop
中阅读所有文件,在rbind
对象中执行计算和result
结果。
path <-"C:/temp/csv/"
list_of_csv_files <- list.files(path)
result <- NULL
for (filenames in list_of_csv_files) {
input <- read.csv(paste0(path,filenames), header=TRUE, stringsAsFactors=FALSE)
#Do your calculations
input_with_calculations <- input
result <- rbind(result,input_with_calculations)
}
result