如何 运行 对数据框中的不同子集进行 glm 编码并使用提取的值创建新列?
How to run glm code over different subsets within dataframe & create new column with the extracted values?
我有这段代码 运行 是一个 glm,用于生成受试者对 "midpoint" 的反应 [编码为 trochiac/iambic、0 或 1]数字刺激列表,将中点保存为一个值并在控制台中打印该值。
glm.1 <- glm(coderesponse~stimulus, family = binomial(link="logit"), data=data)
midpoint <- -glm.1$coefficients[1]/glm.1$coefficients[2]
cat(sprintf("file : %s\nmidpoint : %.2f",datafile,midpoint))
目前,此代码 运行 遍及整个数据帧。我想知道如何修改这段代码,以便我可以 运行 它在我的主数据框中的各个子组上,并为每个子组创建一个包含这些值的新列?
例如对于每个主题,我想为每个 stimtype "bd"、"nm" 和 "nm" 中的每个块 (1-8) 生成中点值。该中点值将是每个 stimtype 中每个块的所有行的新创建列中的新值。
我们最终还希望将要减少的每个块的值聚合到包含中点值的一行(而不是让所有行都具有相同的值)。
我的主数据框的小型虚拟版本(仅包含一个主题和最多 6 个刺激):
subject <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2)
stimulus <- c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1)
block <- c(3, 3, 3, 7, 7, 7, 4, 4, 4, 8, 8, 8, 1, 1, 1, 5, 5, 5, 2, 2, 2, 6, 6, 6, 3, 3, 3, 7, 7, 7, 4, 4, 4, 8, 8, 8, 2, 2, 2, 6, 6, 6)
blockprocedure <- c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1)
stimtype <- c('bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm')
blocktype <- c('mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose')
coderesponse <- c(1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1)
dummy = data.frame(subject, stimulus, block, stimtype, blockprocedure, blocktype, coderesponse)
我最初尝试过,但显然这不是要走的路...:[=14=]
dummy <- data %>%
group_by(subject, stimtype, block)
dummy$test <- NA
glm.1 <- glm(coderesponse~stimulus, family = binomial(link="logit"), data=dummy)
midpoint <- -glm.1$coefficients[1]/glm.1$coefficients[2]
dummy$test <- midpoint
我对编码还很陌生,所以我希望这一切都有意义!
感谢您的任何 help/insight!
我认为这是使用 tidyr::nest
和 purrr::map
组合的好地方。
的确,正如?nest
所说,"Nesting is often useful for creating per group models"。
这是一些代码:
library(dplyr)
library(tidyr)
library(purrr)
get_midpoint = function(data){
glm.1 = glm(coderesponse~stimulus, family = binomial(link="logit"), data=data)
rtn = -glm.1$coefficients[1]/glm.1$coefficients[2]
rtn
}
dummy %>%
nest(data=-c(subject, stimtype, block)) %>%
mutate(midpoint=map_dbl(data, get_midpoint))
# A tibble: 30 x 5
subject block stimtype data midpoint
<dbl> <dbl> <fct> <list> <dbl>
1 1 3 bd <tibble [2 x 4]> -1.69e11
2 1 3 nd <tibble [2 x 4]> -1.69e11
3 1 3 nm <tibble [2 x 4]> -1.69e11
4 1 7 bd <tibble [2 x 4]> 3.00e 0
5 1 7 nd <tibble [2 x 4]> -1.69e11
6 1 7 nm <tibble [2 x 4]> -1.69e11
7 1 4 bd <tibble [2 x 4]> 4.00e 0
8 1 4 nd <tibble [2 x 4]> 4.00e 0
9 1 4 nm <tibble [2 x 4]> -1.96e11
10 1 8 bd <tibble [2 x 4]> 4.00e 0
在这里,您可以在名为 data
的列中 nest
除 c(subject, stimtype, block)
之外的所有列。然后,您可以 map
围绕此列应用自定义函数。作为你的函数 returns a double,我使用了 map_dbl
.
编辑
你也可以使用总结:
dummy %>%
group_by(subject, stimtype, block) %>%
summarise(midpoint = get_midpoint(tibble(coderesponse, stimulus)))
这会输出相同的结果(尽管顺序不同)。
我有这段代码 运行 是一个 glm,用于生成受试者对 "midpoint" 的反应 [编码为 trochiac/iambic、0 或 1]数字刺激列表,将中点保存为一个值并在控制台中打印该值。
glm.1 <- glm(coderesponse~stimulus, family = binomial(link="logit"), data=data)
midpoint <- -glm.1$coefficients[1]/glm.1$coefficients[2]
cat(sprintf("file : %s\nmidpoint : %.2f",datafile,midpoint))
目前,此代码 运行 遍及整个数据帧。我想知道如何修改这段代码,以便我可以 运行 它在我的主数据框中的各个子组上,并为每个子组创建一个包含这些值的新列?
例如对于每个主题,我想为每个 stimtype "bd"、"nm" 和 "nm" 中的每个块 (1-8) 生成中点值。该中点值将是每个 stimtype 中每个块的所有行的新创建列中的新值。
我们最终还希望将要减少的每个块的值聚合到包含中点值的一行(而不是让所有行都具有相同的值)。
我的主数据框的小型虚拟版本(仅包含一个主题和最多 6 个刺激):
subject <- c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2)
stimulus <- c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 1, 1, 1, 1, 1, 1)
block <- c(3, 3, 3, 7, 7, 7, 4, 4, 4, 8, 8, 8, 1, 1, 1, 5, 5, 5, 2, 2, 2, 6, 6, 6, 3, 3, 3, 7, 7, 7, 4, 4, 4, 8, 8, 8, 2, 2, 2, 6, 6, 6)
blockprocedure <- c(1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1)
stimtype <- c('bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm', 'bd', 'nd', 'nm')
blocktype <- c('mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose', 'mouth', 'mouth', 'mouth', 'nose', 'nose', 'nose')
coderesponse <- c(1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1)
dummy = data.frame(subject, stimulus, block, stimtype, blockprocedure, blocktype, coderesponse)
我最初尝试过,但显然这不是要走的路...:[=14=]
dummy <- data %>%
group_by(subject, stimtype, block)
dummy$test <- NA
glm.1 <- glm(coderesponse~stimulus, family = binomial(link="logit"), data=dummy)
midpoint <- -glm.1$coefficients[1]/glm.1$coefficients[2]
dummy$test <- midpoint
我对编码还很陌生,所以我希望这一切都有意义! 感谢您的任何 help/insight!
我认为这是使用 tidyr::nest
和 purrr::map
组合的好地方。
的确,正如?nest
所说,"Nesting is often useful for creating per group models"。
这是一些代码:
library(dplyr)
library(tidyr)
library(purrr)
get_midpoint = function(data){
glm.1 = glm(coderesponse~stimulus, family = binomial(link="logit"), data=data)
rtn = -glm.1$coefficients[1]/glm.1$coefficients[2]
rtn
}
dummy %>%
nest(data=-c(subject, stimtype, block)) %>%
mutate(midpoint=map_dbl(data, get_midpoint))
# A tibble: 30 x 5 subject block stimtype data midpoint <dbl> <dbl> <fct> <list> <dbl> 1 1 3 bd <tibble [2 x 4]> -1.69e11 2 1 3 nd <tibble [2 x 4]> -1.69e11 3 1 3 nm <tibble [2 x 4]> -1.69e11 4 1 7 bd <tibble [2 x 4]> 3.00e 0 5 1 7 nd <tibble [2 x 4]> -1.69e11 6 1 7 nm <tibble [2 x 4]> -1.69e11 7 1 4 bd <tibble [2 x 4]> 4.00e 0 8 1 4 nd <tibble [2 x 4]> 4.00e 0 9 1 4 nm <tibble [2 x 4]> -1.96e11 10 1 8 bd <tibble [2 x 4]> 4.00e 0
在这里,您可以在名为 data
的列中 nest
除 c(subject, stimtype, block)
之外的所有列。然后,您可以 map
围绕此列应用自定义函数。作为你的函数 returns a double,我使用了 map_dbl
.
编辑
你也可以使用总结:
dummy %>%
group_by(subject, stimtype, block) %>%
summarise(midpoint = get_midpoint(tibble(coderesponse, stimulus)))
这会输出相同的结果(尽管顺序不同)。