首页 > 解决方案 > mutate 和 rnorm 的 R 行为

问题描述

您好,我有以下课程代码

library(tidyverse)
library(dslabs)
data("polls_us_election_2016")
head(results_us_election_2016)

results_us_election_2016 %>% arrange(desc(electoral_votes)) %>% top_n(5, electoral_votes)

'Computing the average and standard deviation for each state'

polls <- polls_us_election_2016 %>%
  filter(state != "U.S." &
           !grepl("CD", "state") &
           enddate >= "2016-10-31" &
           (grade %in% c("A+", "A", "A-", "B+") | is.na(grade))) %>%
  mutate(spread = rawpoll_clinton/100 - rawpoll_trump/100) %>%
  group_by(state) %>%
  summarize(avg = mean(spread), sd = sd(spread), n = n()) %>%
  mutate(state = as.character(state))
# joining electoral college votes and results
results <- left_join(polls, results_us_election_2016, by="state")
head(results)

# states with no polls: note Rhode Island and District of Columbia = Democrat
results_us_election_2016 %>% filter(!state %in% results$state)

# assigns sd to states with just one poll as median of other sd values
results <- results %>%
  mutate(sd = ifelse(is.na(sd), median(results$sd, na.rm = TRUE), sd))

#Calculating the posterior mean and posterior standard error

mu <- 0
tau <- 0.02
results %>% mutate(sigma = sd/sqrt(n),
                   B = sigma^2/ (sigma^2 + tau^2),
                   posterior_mean = B*mu + (1-B)*avg,
                   posterior_se = sqrt( 1 / (1/sigma^2 + 1/tau^2))) %>%
  arrange(abs(posterior_mean))

#Monte Carlo simulation of Election Night results (no general bias)

mu <- 0
tau <- 0.02
clinton_EV <- replicate(1000, {
  results %>% mutate(sigma = sd/sqrt(n),
                     B = sigma^2/ (sigma^2 + tau^2),
                     posterior_mean = B*mu + (1-B)*avg,
                     posterior_se = sqrt( 1 / (1/sigma^2 + 1/tau^2)),
                     simulated_result = rnorm(length(posterior_mean), posterior_mean, posterior_se),
                     clintonvotes = ifelse(simulated_result > 0, electoral_votes, 0)) %>%    # award votes if Clinton wins state
    summarize(clinton = sum(clintonvotes)) %>%    # total votes for Clinton
    .$clinton + 7    # 7 votes for Rhode Island and DC
})
mean(clinton_EV > 269)    # over 269 votes wins election

我不明白这条线是如何工作的

simulated_result = rnorm(length(posterior_mean), posterior_mean, posterior_se)

length(posterior_mean) = 47,所以rnorm应该返回一个大小为 47 的向量。当我用 1 替换它时,每个状态都会从 rnorm 得到相同的结果,尽管每个状态的后均值和后验是不同的。当我将其更改为 46 时,出现错误。所以在我看来,这条线填满了整个列simulated_result(可能是47次,结果相同?)。我原以为 mutate 只使用每一行的值来操纵这个特定的行。

也许有人可以向我解释这种行为或将我指向解释这种行为的资源?

标签: rdplyr

解决方案


对于该rnorm功能,如果您检查小插图:

rnorm(n, mean = 0, sd = 1) Arguments

x, q    :vector of quantiles. 
p   :vector of probabilities. 
n   :number of observations. If length(n) > 1, the length is taken to be the number required. 
mean    :vector of means. 
sd  :vector of standard deviations.

有两种使用它的方法,一种是生成一个长度为 n 的向量,来自相同均值和 sd 的正态分布,例如:

set.seed(111)
rnorm(10,0,1) 
 [1]  0.2352207 -0.3307359 -0.3116238 -2.3023457 -0.1708760  0.1402782 -1.4974267 -1.0101884
 [9] -0.9484756 -0.4939622

如果您提供与 n 一样长的向量,则您正在为每个条目指定均值和 sd,例如:

set.seed(111)
rnorm(10,1:10,1:10)
 [1]  1.23522071  1.33852826  2.06512853 -5.20938263  4.14561978  6.84166935 -3.48198659 -0.08150735
 [9]  0.46371956  5.06037783

在这种情况下,您生成一个包含 10 个随机正态变量的向量,第一个条目来自 mean=1、sd=1、第二个条目 mean=2、sd=2 等等。我们还可以在两者之间做一些事情:

set.seed(111)
rnorm(10,1:10,1))
[1] 1.235221 1.669264 2.688376 1.697654 4.829124 6.140278 5.502573 6.989812 8.051524 9.506038

在这种情况下,它返回一个长度为 10 的向量,第一个条目来自 mean = 1,sd=1,第二个来自 mean =2,sd =1,我们可以通过重新运行来可视化它:

t(replicate(10,rnorm(10,1:10,1)))

在此处输入图像描述

您用 1 替换的内容不是很清楚,但本质上 mutate 的目的是为一列分配值。模拟结果列的工作方式与上述类似。


推荐阅读