使用 lapply 在多个数据框上创建新变量

dmalex

我已经搜索了所有lapply问题和解决方案,但这些解决方案似乎都没有解决和/或适用于以下问题......

我有一个列表“temp”,其中包含 100 个数据帧的名称:“sim_rep1.dat”到“sim_rep100.dat”。

每个数据框有 2000 个观察值和相同的 11 个变量:ARAND 和 w1-w10,所有这些都是数字。

对于所有 100 个数据帧,我试图创建一个名为“ps_true”的新变量,该变量包含某些“w”变量,每个变量都有一个唯一的系数。

对我有用的 lapply 的唯一用法如下:

lapply(mget(paste0("sim_rep", 1:100,".dat")), transform, 
            ps_true = (1 + exp(-(0.8*w1 - 0.25*w2 + 0.6*w3 - 
                       0.4*w4 - 0.8*w5 - 0.5*w6  + 0.7*w7)))^-1)

当我运行上面的代码时,R 循环遍历所有 100 个数据帧并在控制台中显示新计算的 ps_true 值。不幸的是,新列没有添加到数据框中。

当我尝试创建一个函数时,轮子完全脱落了。

我尝试了以下不同的变体:

 lapply(temp, function(x){       
        ps_true = (1 + exp(-(0.8*w1 - 0.25*w2 + 0.6*w3 - 
                       0.4*w4 - 0.8*w5 - 0.5*w6  + 0.7*w7)))^-1
   cbind(x, ps_true)
   return(x)
 })
  • FUN(X[[i]], ...) 中的错误:未找到对象 'w1'来自上述函数的结果
  • x$w1 中的错误:如果我尝试引用 x$w1,$ 运算符对于原子向量结果无效
  • FUN(X[[i]], ...) 中的错误:如果我尝试引用 x[[w1]],则未找到对象 'w1'结果
  • x[["w1"]] 中的错误:如果我尝试引用 x[["w1"]] 则下标越界结果

我希望有一些明显的东西是我遗漏的。我很感激你的见解和建议来解决这个令人沮丧的问题。

回应 Uwe 的附录:

我用来读取所有文件的代码如下:

temp = list.files(pattern='*.dat')
for (i in 1:length(temp)) {
    assign(temp[i], read.csv(temp[i], header=F,sep="",
           col.names = c("ARAND", "w1", "w2", "w3", "w4", "w5", "w6", "w7", "w8", "w9", "w10")))
}
乌韦

根据 OP,有 100 个具有相同列名的 data.frames。OP 希望使用完全相同的公式在所有 data.frames 中创建一个新列。

这表明数据结构设计存在根本性缺陷。我想,没有数据库管理员会创建 100 个相同的表,其中只有数据内容不同。相反,他会创建一个带有附加列的表,用于标识每一行的来源。然后,所有后续操作将应用于一个表,而不是对许多表中的每一个重复。

在 R 中,data.table包具有rbindlist()可用于此目的的便捷功能:

library(data.table)   # CRAN version 1.10.4 used
# get list of data.frames from the given names and
# combine the rows of all data sets into one large data.table
DT <- rbindlist(mget(temp), idcol = "origin")
# now create new column for all rows across all data sets
DT[, ps_true := (1 + exp(-(0.8*w1 - 0.25*w2 + 0.6*w3 - 
                            0.4*w4 - 0.8*w5 - 0.5*w6  + 0.7*w7)))^-1]
DT
                origin ARAND   w1   w2   w3   w4   w5   w6   w7   w8   w9  w10   ps_true
     1:   sim_rep1.dat  -0.6 -0.5  0.2 -0.7  0.5  2.4 -0.2 -0.9 -1.1  0.3 -0.8 0.0287485
     2:   sim_rep1.dat  -0.2  0.2  0.7  1.0  1.8 -0.2  0.8  0.3 -1.3 -1.6 -0.2 0.4588433
     3:   sim_rep1.dat   1.6 -0.5  0.7 -0.7 -1.7  0.9 -1.2 -1.0  1.1 -0.3 -2.1 0.2432395
     4:   sim_rep1.dat   0.1  1.2 -1.3 -0.1  0.3 -0.6  0.4  0.3  0.8 -1.2 -1.7 0.8313184
     5:   sim_rep1.dat   0.1  0.2 -2.0  0.6 -0.3  0.2  0.2  0.5 -0.9 -0.8 -1.1 0.7738186
    ---                                                                                 
199996: sim_rep100.dat   0.1 -1.4  1.6 -0.7 -1.0 -0.6  0.8 -0.6 -0.5 -0.4 -0.8 0.1323889
199997: sim_rep100.dat   0.3  1.3 -2.4 -0.7 -0.4  0.0  1.0 -0.2  1.0 -0.1  0.3 0.6769959
199998: sim_rep100.dat   0.3  1.2  0.0 -1.3 -0.8 -0.7 -0.3  0.1  0.9  0.9 -1.3 0.7824498
199999: sim_rep100.dat   0.5 -0.7  0.2  0.5  1.1 -0.3  0.3 -0.5 -0.8  1.9 -0.7 0.2669799
200000: sim_rep100.dat  -0.5  1.1  0.8  0.2 -0.6 -0.5 -0.4  1.1 -1.8  0.9 -1.3 0.9175867

DT现在由 20 万行组成。性能无需担心,因为它data.table是为有效处理大型(甚至更大)数据而构建的。


如果需要单独处理各个数据集的数据,则可以识别每行的来源。例如,

DT[origin == "sim_rep47.dat"]
             origin ARAND   w1   w2   w3   w4   w5   w6   w7   w8   w9  w10   ps_true
   1: sim_rep47.dat  -0.6 -0.5  0.2 -0.7  0.5  2.4 -0.2 -0.9 -1.1  0.3 -0.8 0.0287485
   2: sim_rep47.dat  -0.2  0.2  0.7  1.0  1.8 -0.2  0.8  0.3 -1.3 -1.6 -0.2 0.4588433
   3: sim_rep47.dat   1.6 -0.5  0.7 -0.7 -1.7  0.9 -1.2 -1.0  1.1 -0.3 -2.1 0.2432395
   4: sim_rep47.dat   0.1  1.2 -1.3 -0.1  0.3 -0.6  0.4  0.3  0.8 -1.2 -1.7 0.8313184
   5: sim_rep47.dat   0.1  0.2 -2.0  0.6 -0.3  0.2  0.2  0.5 -0.9 -0.8 -1.1 0.7738186
  ---                                                                                
1996: sim_rep47.dat   0.1 -1.4  1.6 -0.7 -1.0 -0.6  0.8 -0.6 -0.5 -0.4 -0.8 0.1323889
1997: sim_rep47.dat   0.3  1.3 -2.4 -0.7 -0.4  0.0  1.0 -0.2  1.0 -0.1  0.3 0.6769959
1998: sim_rep47.dat   0.3  1.2  0.0 -1.3 -0.8 -0.7 -0.3  0.1  0.9  0.9 -1.3 0.7824498
1999: sim_rep47.dat   0.5 -0.7  0.2  0.5  1.1 -0.3  0.3 -0.5 -0.8  1.9 -0.7 0.2669799
2000: sim_rep47.dat  -0.5  1.1  0.8  0.2 -0.6 -0.5 -0.4  1.1 -1.8  0.9 -1.3 0.9175867

提取属于数据集的所有行sim_rep47.dat

数据

为了测试和演示,我使用以下代码创建了 100 个示例 data.frames:

# create vector of file names
temp <- paste0("sim_rep", 1:100, ".dat")
# create one sample data.frame
nr <- 2000L
nc <- 11L
set.seed(123L)
foo <- as.data.frame(matrix(round(rnorm(nr * nc), 1), nrow = nr))
names(foo) <- c("ARAND", paste0("w", 1:10))
str(foo)
# create 100 individually named data.frames by "copying" foo
for (t in temp) assign(t, foo)
# print warning message on using assign
fortunes::fortune(236)
# verify objects have been created
ls()

附录:一次读取所有文件

该OP评选的单data.frames sim_rep1.datsim_rep2.dat等它类似于典型的文件名。以防万一 OP 确实在磁盘上有 100 个文件,我想建议一种方法来一次读取所有文件。假设所有文件都存储在一个目录中。

# path to data directory
data_dir <- file.path("path", "to", "data", "directory")
# create vector of file paths
files <- dir(data_dir, pattern = "sim_rep\\d+\\.dat", full.names = TRUE)
# read all files and create one large data.table
# NB: it might be necessary to add parameters to fread() 
# or to use another file reader depending on the file type
DT <- rbindlist(lapply(files, fread), idcol = "origin")
# rename origin to contain the file names without path
DT[, origin := factor(origin, labels = basename(files))]
DT
               origin ARAND   w1   w2   w3   w4   w5   w6   w7   w8   w9  w10   ps_true
     1:  sim_rep1.dat  -0.6 -0.5  0.2 -0.7  0.5  2.4 -0.2 -0.9 -1.1  0.3 -0.8 0.0287485
     2:  sim_rep1.dat  -0.2  0.2  0.7  1.0  1.8 -0.2  0.8  0.3 -1.3 -1.6 -0.2 0.4588433
     3:  sim_rep1.dat   1.6 -0.5  0.7 -0.7 -1.7  0.9 -1.2 -1.0  1.1 -0.3 -2.1 0.2432395
     4:  sim_rep1.dat   0.1  1.2 -1.3 -0.1  0.3 -0.6  0.4  0.3  0.8 -1.2 -1.7 0.8313184
     5:  sim_rep1.dat   0.1  0.2 -2.0  0.6 -0.3  0.2  0.2  0.5 -0.9 -0.8 -1.1 0.7738186
    ---                                                                                
199996: sim_rep99.dat   0.1 -1.4  1.6 -0.7 -1.0 -0.6  0.8 -0.6 -0.5 -0.4 -0.8 0.1323889
199997: sim_rep99.dat   0.3  1.3 -2.4 -0.7 -0.4  0.0  1.0 -0.2  1.0 -0.1  0.3 0.6769959
199998: sim_rep99.dat   0.3  1.2  0.0 -1.3 -0.8 -0.7 -0.3  0.1  0.9  0.9 -1.3 0.7824498
199999: sim_rep99.dat   0.5 -0.7  0.2  0.5  1.1 -0.3  0.3 -0.5 -0.8  1.9 -0.7 0.2669799
200000: sim_rep99.dat  -0.5  1.1  0.8  0.2 -0.6 -0.5 -0.4  1.1 -1.8  0.9 -1.3 0.9175867

所有数据集现在都存储在一个DT由 20 万行组成的大型 data.table中。但是,数据集的顺序是不同的,因为files按字母顺序排序,即,

head(files)
[1] "./data/sim_rep1.dat"   "./data/sim_rep10.dat"  "./data/sim_rep100.dat"
[4] "./data/sim_rep11.dat"  "./data/sim_rep12.dat"  "./data/sim_rep13.dat"

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用lapply基于旧列创建新列

R:使用lapply添加新列

如何修改多个数据框而不列出它们,然后使用lapply?

如何使用lapply定义多个变量?

R-在一个数据帧中合并两列,创建新的列标题,使用lapply在大型数据集上重复并合并

使用lapply标记特定变量的值

lapply()在数据框的多个列上使用函数

使用lapply根据多个条件和子集创建新变量

data.table:使用lapply和.SD创建多个列

R:如何对每月数据使用lapply

如何使用lapply()创建多个数据框?

将lapply与for和if..else语句结合使用可将条件列添加到多个数据框

使用lapply和gsub处理数据帧

在read.csv中使用lapply变量

使用lapply基于两个或多个因子变量对数据框进行子集

R data.table使用lapply创建自定义函数来创建和重新分配多个变量

使用for循环或lapply从一个数据帧中的选择列创建多个ggplots

如何使用Loop或Lapply从矩阵生成100个新变量?

使用lapply从数据帧列表创建新数据帧

如何在R中使用lapply对包含多个数据帧的列表进行采样?

在多个函数上使用lapply

使用lapply中的函数创建新的聚合R数据帧

使用Lapply在多个数据框中查找单个均值-错误的维数不正确

R使用Lapply处理多个数据帧

如何使用lapply在数据框中创建新变量并将其重命名

使用嵌套的 lapply 过滤条件并创建多个数据框

使用 `lapply` 获取多个下载/结果

使用 lapply 或 loop 重复基于多个数据帧创建 .png 文件的过程

在数据帧上使用 lapply 创建带标签的直方图