生成用户定义的 R 函数(或嵌套多个函数)以将原始数据帧子集化为每个人的新数据帧

Producing a user defined R function (or nesting several functions) to subset original dataframe into new dataframes for each individual

我在 R 中遇到了一个可能非常简单的问题,但我缺乏编写用户定义函数的经验也无济于事。

示例数据

individual = c(1, 1, 1, 1, 2, 2, 2, 2), measure1 = c(40, 
70, 90, 100, 40, 70, 90, 100), measure2 = c(1.06, 0.7, 0.507, 
0.37, 0.9, 0.56, 0.412, 0.375)), class = "data.frame", row.names = c(NA, 
-8L))

我正在尝试做什么

简而言之,我想为用户创建一个可以执行以下操作的定义函数:

  1. 取一个数据框,对数据进行子集化,以便只留下测量 1 和测量 2 的相关行。
  2. 获取子集数据并为数据集中的每个人创建一个新的数据框。
  3. 在每个新数据帧上,按以下形式创建线性模型 lm(measure1~measure2, data)

我的thoughts/what我试过了 首先,可能值得我弄清楚 为什么 我想要一个函数来执行此操作。简而言之,我有大约 10 个相似的数据集。我想对所有数据集执行这些操作。我 可以 只创建 1 个大数据集并将它们组合起来,但后勤工作存在问题。所以,我决定写一个函数会更容易。

问题1

Filt.data<- function(x,y,z){
new.data<<-x[x$measure1 %in% c(y,z), ]
new.data
}

上面的代码运行良好,允许我使用变量 y 和 z(这是度量 1 的两个值)输入任何数据帧“x”和子集。这是很好的第一步,但这显然会生成一个包含所有参与者数据的新数据框 1:i。所以,我的下一步是在函数中嵌套一个 for 循环。我想出了以下

filt.data<- function(x,y,z){
for (i in 1:length(x$participant)){
x[x$measure1 %in% c(y,z), ]
}
}

这就是我所知道的。在这一点上让我感到困惑的是如何为每个参与者创建一个新的数据框 1:i 并唯一命名(即,new.dat_1),其中“1”是参与者(或类似的东西)。一旦我完成了这一步,我就可以简单地 运行 数据帧上的线性模型作为我认为的列表?但是后来我 运行 又遇到了同样的问题:How do I create a variable to store the results for each linear model?

我是 R 的新手,并不经常使用它。我试过查找类似的问题,但是整个索引 [[i]] 符号让我很困惑!所以,快速请求:如果有人觉得他们能够生成代码,他们是否也可以添加一些注释?这将极大地帮助我将来能够再次这样做,并了解其机制。

一如既往,感谢那些抽出时间 (1) 阅读本文并 (2) 提供支持的英雄们!

干杯。

不是一个好习惯
  • 从函数内部写入全局环境。避免使用 <<-assign.
  • 为每个 individual 创建单独的数据帧。您应该改用列表。

试试这个方法:

Filt.data<- function(x,y,z) {
  dat <- subset(x, measure1 %in% c(y,z))
  lapply(split(dat, dat$individual), function(x) lm(measure1~measure2, x))
}

list_model <- Filt.data(df, 40, 70)
list_model

#$`1`

#Call:
#lm(formula = measure1 ~ measure2, data = x)

#Coefficients:
#(Intercept)     measure2  
#     128.33       -83.33  


#$`2`

#Call:
#lm(formula = measure1 ~ measure2, data = x)

#Coefficients:
#(Intercept)     measure2  
#     119.41       -88.24  

数据

df <- data.frame(individual = c(1, 1, 1, 1, 2, 2, 2, 2),
                 measure1 = c(40, 70, 90, 100, 40, 70, 90, 100), 
                 measure2 = c(1.06, 0.7, 0.507, 0.37, 0.9, 0.56, 0.412, 0.375))