如何使用R在Stata中执行诸如foreach之类的操作?

时间:2019-05-29 01:38:50

标签: r loops foreach stata

我是R新手,正在使用Stata。我可以在Stata中使用foreach和forvalue遍历变量。

我想遍历列而不是遍历行。例如,我有一个名为var1,var2,var3的列。数据如下:

var1 var2 var3
  1    1   1   
  2   999  3
 999   2  999

我想将变量中的所有“ 999”值重新编码为丢失。在Stata中,我可以做到

forvalue i = 1(1)3{
  replace var`i' ="NA" if var`i' =="999"
}

因此,我的结果就像

var1 var2 var3
  1    1   1   
  2   NA   3
  NA   2  NA

此外,如果我有名为ht,wgt,bmi的列,我想计算该列的均值并将该均值存储在具有相应名称的新列中。数据集如下:

 ht     wgt   bmi
154.5  43.1 18.1
164.2  63   23.4

在Stata中,我可以做

foreach i of varlist ht wgt bmi{
  gen `i'mean = mean(`i')
}

结果将是

 ht    wgt   bmi  htmean wgtmean bmimean
154.5  43.1 18.1  159.35  53.05   20.75
164.2  63   23.4  159.35  53.05   20.75

我不知道如何使用R。

3 个答案:

答案 0 :(得分:2)

有很多不同的方式来做这些事情。例如。对于身高,体重,BMI示例,您可以使用for循环,基本上与在Stata中一样进行此操作:

# For-loop approach
for (col in c("ht", "wgt", "bmi")) {
    new_col = paste0(col, "_mean")
    df2[, new_col] = mean(df2[, col])
}

区别是代码中的符号和R中的字符串之间有更强的分隔,因此您可以将列名称指定为字符串,使用paste0创建表示新列名称的字符串,然后将它们添加到数据框中

另一种实现方法是使用dplyr包和mutate_at函数,这会将相同的转换应用于多个列:

library(dplyr)

df2 %>%
    mutate_at(c("ht", "wgt", "bmi"), 
              list(mean = ~ mean(.)))

语法有点棘手:首先我们给列名命名,然后下一个参数显示我们要如何转换列。 .是当前列的占位符,~表示R不会立即尝试计算mean(.),但会等到我们有实际值替代时使用。给转换起一个名字,例如list(transform = ~ . + 2)dplyr会自动使用该名称作为后缀,因此您会得到x_transformy_transform等列名。

答案 1 :(得分:1)

这里有几个选项。我强烈建议添加一些示例数据,以便我们更好地为您提供帮助。根据您的工作,您可以做几件事:

Refused to execute script from 'mydomain.com/js/swiper.min.js?v=190529102248' because its MIME type ('text/html') is not executable

这适用于条件逻辑,使用library(dplyr) mtcars %>% mutate(my_hp = case_when( hp<50~"Small", hp < 100~"Medium", TRUE~"Large" )) 函数创建一个新变量(列),使用mutate函数使用取决于hp值的不同情况。

此外,您还可以使用看起来像这样的基本R方法

case_when

因此,在这种情况下,您将使用链接的mtcars$my_hp <- ifelse(mtcars$hp < 50, "Small", ifelse(mtcars$hp< 100, "Medium", "Large")) 语句来检查条件来创建名为my_hp的新值。

如果您绝对想进行循环(在这种情况下不需要这样做),则可以执行以下操作:

ifelse

答案 2 :(得分:1)

一次重新编码多个变量

我想将变量中的所有“ 999”值重新编码为丢失。在Stata,我可以做

forvalue i = 1(1)3{
  replace var`i' ="NA" if var`i' =="999"
}

(出于完整性考虑,您还可以使用lapply对多个变量进行重新编码。

lapply()函数采用一组变量并应用一个函数,例如ifelse。您需要使用[]子设置(例如)告诉它数据集和变量。 data[,variables]
然后,您定义要执行的操作,这可以是使用变量的任何重新编码等操作。 该函数首先在Stata循环中定义类似于“ i”局部变量的内容:function(var),此处var的作用与i类似。 最后,您需要再次使用lapply说出data[,variables]的结果到哪里,即到新的或重新编码的变量。

这里有个例子:

# Example data
data <- data.frame(
  var1 = c( 1,2,999),
  var2 = c(1,999,2),
  var3 = c(1,3,999)
)

# Object with the names of the variables you like to recode.
vars_to_recode <- c("var1","var2","var3")

# Recoding
data[ ,vars_to_recode] <- lapply(data[ ,vars_to_recode],
                                      function(var)
                                        ifelse(var == 999, NA, var)
                                      )
data

#    var1 var2 var3
# 1    1    1    1
# 2    2   NA    3
# 3   NA    2   NA

此操作实际上更接近Stata的replace,因为原始变量已替换为转换后的变量。

lapply包中的map()purrr的替代方法,但特别是对于编程I(当前)更喜欢基R函数。

包含旧变量均值的新变量

该问题的第二部分也可以使用lapply来回答,即如何通过包含其他方法的变量来获取变量。从原始问题开始:

此外,如果我有名为ht,wgt,bmi的列,我想计算该列的均值并将该均值存储在具有相应名称的新列中。 在Stata,我可以做

foreach i of varlist ht wgt bmi{
  gen `i'mean = mean(`i')
}

使用lapply简单的解决方案计算平均值并将其放入新的变量/列中。之所以可行,是因为R会自动将任何列(“向量”)填充到数据帧的长度(称为“回收”)。

示例数据

df <- data.frame(
      id  = 1:2,
      ht  = c(154.5,164.2),
      wgt = c(43.1 ,63),
      bmi = c(18.1 ,23.4))

定义要更改的变量和新变量的名称。

vars <- names(df[,2:4])

# Names for new variables
newvars <- paste(names(df),"_mean")
newvars
# [1] "ht _mean"  "wgt _mean" "bmi _mean"

生成包含所需变量均值的新变量:

df[,newvars] <- lapply(df[,vars], 
                       function(var)
                           mean(var)
                       )

结果:

df

#   ht  wgt  bmi ht _mean wgt _mean bmi _mean
# 1 154.5 43.1 18.1   159.35     53.05     20.75
# 2 164.2 63.0 23.4   159.35     53.05     20.75