改变存储在列表中的数据框
Altering dataframes stored within a list
我正在尝试编写某种循环函数,使我能够将同一组代码应用于存储在一个列表中的数十个数据帧。每个数据框具有相同的列数并且每列相同 headers,尽管行数因数据框而异。
此数据来自一项以自我为中心的社交网络研究,我从数十名不同的受访者那里收集了 ego-network 边缘列表格式的数据。我使用的数据 collection 软件将每次采访的数据存储在自己的 .csv 文件中。这是特定数据帧 (image of raw data) 的原始数据图像。
为了我的目的,我只需要使用第四、第六和第七列的数据。此外,我只需要最后一列值为 4 的数据行,此时可以完全删除最后一列。最终结果是一个 two-column 数据框,表示人与人之间的关系。
读取数据并将其存储为 object 后,我 运行 以下代码:
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)。这最终是我想要的。
现在我知道我可以 cut-and-paste 同一组代码 100 多次并手动更改文件名,但我不想那样做。相反,我将所有原始 .csv 文件作为数据框存储在一个列表中。我怀疑我可以通过使用 apply
命令之一在所有数据帧上应用相同的代码,但我无法弄清楚。
有没有人对我如何将此基本代码应用于数据框列表有任何建议,以便我最终得到一个包含数据的清理和简化版本的新列表?
非常感谢!
逻辑可以简化。尝试创建自定义函数并应用于所有数据框。
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'的条件。最后,根据该条件对两个目标列进行子集化。我使用了一个名为 'big_list' 的列表来表示所有数据帧。
您没有提供可重现的示例,因此很难解决您的问题。但是,我不希望您的问题得不到解答。使用 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
我正在尝试编写某种循环函数,使我能够将同一组代码应用于存储在一个列表中的数十个数据帧。每个数据框具有相同的列数并且每列相同 headers,尽管行数因数据框而异。
此数据来自一项以自我为中心的社交网络研究,我从数十名不同的受访者那里收集了 ego-network 边缘列表格式的数据。我使用的数据 collection 软件将每次采访的数据存储在自己的 .csv 文件中。这是特定数据帧 (image of raw data) 的原始数据图像。
为了我的目的,我只需要使用第四、第六和第七列的数据。此外,我只需要最后一列值为 4 的数据行,此时可以完全删除最后一列。最终结果是一个 two-column 数据框,表示人与人之间的关系。
读取数据并将其存储为 object 后,我 运行 以下代码:
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)。这最终是我想要的。
现在我知道我可以 cut-and-paste 同一组代码 100 多次并手动更改文件名,但我不想那样做。相反,我将所有原始 .csv 文件作为数据框存储在一个列表中。我怀疑我可以通过使用 apply
命令之一在所有数据帧上应用相同的代码,但我无法弄清楚。
有没有人对我如何将此基本代码应用于数据框列表有任何建议,以便我最终得到一个包含数据的清理和简化版本的新列表?
非常感谢!
逻辑可以简化。尝试创建自定义函数并应用于所有数据框。
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'的条件。最后,根据该条件对两个目标列进行子集化。我使用了一个名为 'big_list' 的列表来表示所有数据帧。
您没有提供可重现的示例,因此很难解决您的问题。但是,我不希望您的问题得不到解答。使用 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