关于我最近提出的问题,我得到了很多很好的反馈并被指导使用dplyr来转换一些数据.我在使用 lm() 时遇到问题,并试图从这个转换后的数据中找到一个斜率,并认为我会提出一个新问题.
I got a lot of good feedback on a question I recently asked and was guided to use dplyr to transform some data. I'm having an issue with lm() and trying to find a slope from this transformed data and thought I'd open up a new question.
首先我有如下所示的数据:
First I have data that looks like this:
Var1 Var2 Var3 Time Temp a w j 9/9/2014 20 a w j 9/9/2014 15 a w k 9/20/2014 10 a w j 9/10/2014 0 b x L 9/12/2014 30 b x L 9/12/2014 10 b y k 9/13/2014 20 b y k 9/13/2014 15 c z j 9/14/2014 20 c z j 9/14/2014 10 c z k 9/14/2014 11 c w l 9/10/2014 45 a d j 9/22/2014 20 a d k 9/15/2014 4 a d l 9/15/2014 23 a d k 9/15/2014 11我想要它的形式(Slope 和 Pearson 的模拟值用于说明):
And I want it in the form of this (values for Slope and Pearson simulated for illustration):
V1 V2 V3 Slope Pearson a w j -3 -0.9 a w k 2 0 a d j 1.5 0.6 a d k 0 0.5 a d l -0.5 -0.6 b x L 12 0.7 b y k 4 0.6 c z j -1 -0.5 c z k -3 -0.4 c w l -10 -0.9斜率是线性最小二乘斜率.理论上,脚本看起来像这样:
The slope being a linear-least-squares slope. In theory, the script would look like so:
library(dplyr) data <- read.table("clipboard",sep=" ",quote="",header=T) newdata = summarise(group_by(data ,Var1 ,Var2 ,Var3 ) ,Slope = lm(Temp ~ Time)$coeff[2] ,Pearson = cor(Time, Temp, method="pearson") )但是 R 会抛出一个错误,比如它找不到时间或温度.它可以运行 lm(data$Temp ~ data$Time)$coeff[2],但返回整个数据集的斜率,而不是我正在寻找的子集形式.cor() 似乎在 group_by 部分运行得很好,所以我需要传递给 lm() 的特定语法它以类似的方式运行还是完全使用不同的函数来获得从子集传递的斜率?
But R throws an error like it can't find Time or Temp. It can run lm(data$Temp ~ data$Time)$coeff[2], but returns the slope for the entire data set and not the subsetted form that I'm looking for. cor() seems to run just fine in the group_by section, so is there a specific syntax I need to pass to lm() to have it run in a similar manner or use a different function entirely to get a slope passed from the subset?
推荐答案这里有几个问题.
这是仅在 V1
data %>% group_by(Var1) %>% # You can add here additional grouping variables if your real data set enables it do(mod = lm(Temp ~ Time, data = .)) %>% mutate(Slope = summary(mod)$coeff[2]) %>% select(-mod) # Source: local data frame [3 x 2] # Groups: <by row> # # Var1 Slope # 1 a 12.66667 # 2 b -2.50000 # 3 c -31.33333如果你有两个数字变量,你也可以使用 do 来计算相关性,例如(我会创建一些虚拟数字变量来说明)
If you do have two numeric variables, you can use do in order to calculate correlation too, for example (I will create some dummy numeric variables for illustration)
data %>% mutate(test1 = sample(1:3, n(), replace = TRUE), # Creating some numeric variables test2 = sample(1:3, n(), replace = TRUE)) %>% group_by(Var1) %>% do(mod = lm(Temp ~ Time, data = .), mod2 = cor(.$test1, .$test2, method = "pearson")) %>% mutate(Slope = summary(mod)$coeff[2], Pearson = mod2[1]) %>% select(-mod, -mod2) # Source: local data frame [3 x 3] # Groups: <by row> # # Var1 Slope Pearson # 1 a 12.66667 0.25264558 # 2 b -2.50000 -0.09090909 # 3 c -31.33333 0.30151134奖励解决方案:您也可以使用 data.table 包非常有效/轻松地完成此操作
Bonus solution: you can do this quite efficiently/easily with data.table package too
library(data.table) setDT(data)[, list(Slope = summary(lm(Temp ~ Time))$coeff[2]), Var1] # Var1 Slope # 1: a 12.66667 # 2: b -2.50000 # 3: c -31.33333或者如果我们也想创建一些虚拟变量
Or if we want to create some dummy variables too
library(data.table) setDT(data)[, `:=`(test1 = sample(1:3, .N, replace = TRUE), test2 = sample(1:3, .N, replace = TRUE))][, list(Slope = summary(lm(Temp ~ Time))$coeff[2], Pearson = cor(test1, test2, method = "pearson")), Var1] # Var1 Slope Pearson # 1: a 12.66667 -0.02159168 # 2: b -2.50000 -0.81649658 # 3: c -31.33333 -1.00000000更多推荐
线性模型和 dplyr
发布评论