1

我有一个包含连续变量和两个分类 ID 变量的数据集。我想缩放我的数据,使得连续变量对于每个 ID 的某个值具有 1 的值。我尝试将它实现为 R 中的一个函数,这样我就可以避免重复编码。

此外,我有一个在 Stata 中实现的重新缩放的示例:

 gen value_var_i_k= value_var if ID1=="15t16" & ID2 =="AUS"
 egen value_var_i_k_m = mean(value_var_i_k)
 drop value_var_i_k
 rename value_var_i_k_m value_var_i_k

 gen value_var_k= value_var if ID1 =="15t16"
 bys ID2: egen value_var_k_m = mean(value_var_k)
 drop value_var_k
 rename value_var_k_m value_var_k

 gen value_var_i = value_var if ID2=="AUS"
 bys ID1:   egen value_var_i_m = mean(value_var_i)
 drop value_var_i
 rename value_var_i_m value_var_i

 gen value_var_i_k_norm= value_var * value_var_i_k/(value_var_i*value_var_k)    

我在 R 中尝试使用新变量创建value_var_i value_var_kandvalue_var_i_k变量,该变量因错误而退出(不适用于类“字符”的方法):

library(dplyr)
library(magrittr)
normalize<-function(var,data,i,k) { 

varname <- paste("value", var , sep="_")
#Id columns and define variables to select
col1<-"ID1"
col2<-"ID2"
select_variables<-c(col2,col1,varname)

#name of the output variables
name_ik<-paste(i,k,sep="_")
name.ik<-paste(name_ik, "df", sep="_")

name.i<-paste(i, "df", sep="_")

name.k<-paste(k, "df", sep="_")

#my attempt to replicate the Stata code with dplyr

data %>% filter_(as.name(col1)==as.name(i) & as.name(col2)==as.name(k)) %>% select_( .dots=select_variables) %$% as.name( name.ik)

data  %>% filter_(as.name(col1)==as.name(i)) %>% select_( .dots = select_variables ) %>%  group_by_(as.name(col2)) %>%transform( interp(~mean(b, na.rm = TRUE),b=as.name(varname) ))  %$% as.name(name.i)


data %>% filter_(as.name(col2)==as.name(k)) %>% select_( .dots =    select_variables ) %>%  group_by_(as.name(col1)) %>%transform( interp(~mean(b, na.rm = TRUE),b=as.name(varname) )) %$%  as.name(name.k)

norm    <- data[eval(substitute(varname)]*as.name(name.ik)/ ( as.name(name.i) * as.name(name.k) ) 

}

更新二:计算步骤的最小工作示例:value_var两个表中的变量相同。Stata 代码将value_var_kandvalue_var_i变量替换为变量value_var_i_mand value_var_k_m。然后value_var变身。

  value_var  ID1    ID2  value_var_i_k value_var_k  value_var_k_m

1.154662    15t16   AUS 1.154662    1.154662     1.154662
1.070471    17t18   AUS 1.154662        .        1.154662
0.9643197   19      AUS 1.154662        .        1.154662
1.036398    20      AUS 1.154662        .        1.154662
1.084701    21t22   AUS 1.154662        .        1.154662

1.463215    15t16   AUT 1.154662    1.463215     1.463215
1.431824    17t18   AUT 1.154662        .        1.463215
1.276983    19      AUT 1.154662        .        1.463215
1.441925    20      AUT 1.154662        .        1.463215
1.506117    21t22   AUT 1.154662        .        1.463215

1.589491    15t16   BEL 1.154662    1.589491     1.589491
1.540076    17t18   BEL 1.154662        .        1.589491
1.188218    19      BEL 1.154662        .        1.589491
1.386074    20      BEL 1.154662        .        1.589491
1.48204   21t22     BEL 1.154662        .        1.589491


value_var   ID1    ID2  value_var_i value_var_i_m
1.154662    15t16   AUS 1.154662    1.154662
1.589491    15t16   BEL   .         1.154662
1.463215    15t16   AUT   .         1.154662

1.070471    17t18   AUS 1.070471    1.070471
1.540076    17t18   BEL   .         1.070471
1.431824    17t18   AUT   .         1.070471

0.9643197   19      AUS 0.9643197   0.9643197
1.276983    19      AUT     .       0.9643197
1.188218    19      BEL     .       0.9643197

1.036398    20      AUS 1.036398    1.036398
1.441925    20      AUT     .       1.036398
1.386074    20      BEL     .       1.036398

1.084701    21t22   AUS 1.084701    1.084701  
1.506117    21t22   AUT      .      1.084701
1.48204     21t22   BEL      .      1.084701

归一化值 var 如下(对 ID1 级别“15t16”和 ID2 级别“AUS”进行归一化):

      ID1    ID2  value_var_i_k_norm

      AUS   15t16   1
      AUS   17t18   1
      AUS   19      1
      AUS   20      1
      AUS   21t22   1
      AUT   15t16   1
      AUT   17t18   1.055508
      AUT   19      1.044988
      AUT   20      1.097901
      AUT   21t22   1.09571
      BEL   15t16   1
      BEL   17t18   1.045116
      BEL   19      .8951011
      BEL   20      .9715319
      BEL   21t22   .9925373

更新:为了使标准化(或缩放)步骤更清晰,我在这里以宽格式显示标准化数据的 pre after。

首先我从以下广泛的数据开始

 Row-/Colnames     15t16        17t18        19t         20t      21t22
   AUS           1.154662   1.070471    0.9643197   1.036398    1.084701
   AUT           1.463215   1.431824    1.276983    1.441925    1.506117
   BEL           1.589491   1.540076    1.188218    1.386074    1.48204

我将矩阵规范化为具有 AUS 值的行和具有 15t16 值的列。所以,我会得到

     Row-/Colnames  15t16      17t18         19t         20t      21t22
          AUS          1         1          1           1           1
          AUT          1    1.055508    1.044988    1.097901    1.09571
          BEL          1    1.045116    .8951011    .9715319    .9925373
4

3 回答 3

2

所以,如果我根据您的编辑正确理解您。

这是您的“标准化”例程:

If (ID1 == "AUS" | ID2 == "15t16") {value_var == 1}
else {value_var unchanged}

这很容易通过ifelse(假设输入data.frame名为df)完成:

df$value_var <- ifelse(df$ID1 == "AUS" | df$ID2 == "15t16", 1, df$value_var)

同样,我不愿称其为“规范化”,但它确实符合您的描述。通常,在统计上下文中,归一化意味着缩放——即减去平均值并除以 SD。但你似乎没有在这里这样做。

于 2016-05-20T22:09:42.620 回答
1

这太长了,不适合作为评论。但是我可以将你的 Stata 代码从 13 行减少到 5 行,我希望借此让你正在做的事情对使用 Stata 或 R 或​​两者的人更清楚。我保留您的代码块并添加注释。

* no need to use -egen- to create a single mean; use -summarize- results 
summarize value_var if ID1=="15t16" & ID2=="AUS", meanonly 
gen value_var_i_k = r(mean) 

* evaluating ID1 == "15t16" yields 1 or 0; dividing by 0 yields missing values 
* which are ignored, which is what you want 
bys ID2: egen value_var_k = mean(value_var / (ID1=="15t16")) 

* same device as previous block 
bys ID1: egen value_var_i = mean(value_var / (ID2=="AUS")) 

gen value_var_i_k_norm = value_var * value_var_i_k/(value_var_i * value_var_k)  

事实上,我们可以进一步减少,但这个版本不太清楚:

bys ID2: egen value_var_k = mean(value_var / (ID1=="15t16")) 
bys ID1: egen value_var_i = mean(value_var / (ID2=="AUS")) 
summarize value_var if ID1=="15t16" & ID2=="AUS", meanonly     
gen value_var_i_k_norm = value_var * r(mean)/(value_var_i * value_var_k)    

对于除以零设备,请参阅这篇文章,第 10 节。忽略某些观察的另一种方法是

bys ID1: egen value_var_i = mean(cond(ID2=="AUS", value_var, .))  

这在同一篇文章第 9 节中进行了讨论。

无论哪种方式,一个关键细节是忽略缺失值的mean()功能。egen

于 2016-05-21T08:43:06.627 回答
0

我现在看到我翻译 Stata 代码的尝试导致我在 R 中误入歧途。规范化变量只是针对特定 ID 值过滤原始数据帧的结果,在下一步中,我将它们与原始数据进行内部连接框架。

normalize<-function(data,var,col1,col2,i,k) { 

varname <- paste("z.ik", var , sep="_")
var.i<-paste(var,i, sep="_")
var.k<-paste(var,k, sep="_")
var.ik<-paste(var.i,k, sep="_")
varname_i <- paste("z", var.i , sep="_")
varname_k <- paste("z", var.k , sep="_")
varname_ik <- paste("z", var.ik , sep="_")

d2<-select_(data, varname, col1, col2)
filter_crit2 = interp(~ filter_var1 %in% i & filter_var2 %in% k   ,.values = list(filter_var1 = as.name(col1),filter_var2 = as.name(col2)))
filter_crit_k = interp(~  filter_var2 %in% k ,.values =   list(filter_var2 = as.name(col2)))
filter_crit_i = interp(~ filter_var1 %in% i  ,.values =   list(filter_var1 = as.name(col1)))
select_variables.k<-c(col2,varname)
select_variables.i<-c(col1,varname)
results_ik<- data %>% filter_(    filter_crit2 )  %>% select_( .dots=varname )  %>%rename_(.dots=setNames( varname, varname_ik))
results_ik<-cbind(  results_ik ,d2)
results_i<- data %>% filter_(    filter_crit_i )  %>% select_( .dots=select_variables.k) %>%rename_(.dots=setNames( varname, varname_i)) %>%inner_join( ., results_ik)
results_k<- data %>% filter_(    filter_crit_k )  %>% select_( .dots=select_variables.i) %>%rename_(.dots=setNames( varname, varname_k)) %>% inner_join( .,   results_i)

  mutate_fn <- function(d_in,  varval,  varname_norm){
   d_out = d_in %>%
  mutate_(.dots = setNames(  varval,  varname_norm))
  }
d_in=results_k
varname_norm<- paste("z", var, sep="_")
varname_norm <- paste(varname_norm,"norm", sep="_")
varval <- lazyeval::interp(~ var1* var2 / (var3 * var4),.values=   list( var1=as.name(varname) , var2=as.name(varname_ik),    var3=as.name(varname_i), var4=as.name(varname_k)))  

data.norm = mutate_fn(d_in,varval,varname_norm )
n<-length(data.norm)
names(data.norm)[n]<-varname_norm 
data.norm <-select_(       data.norm,.dots=c(col1,col2,varname,varname_norm))
 }
于 2016-05-21T07:04:49.213 回答