【问题标题】:What is the equivalent of Stata function inlist() in R?R中的Stata函数inlist()的等价物是什么?
【发布时间】:2012-12-27 01:01:51
【问题描述】:

Stata 的inlist 允许我们引用变量的真实值或字符串值。我想知道R是否有这样的功能。

示例:

我想从变量state 中选择八个州(您可以将其视为statestate 采用50 个字符串值(美国各州)的任何数据框中的列)。

    inlist(state,"NC","AZ","TX","NY","MA","CA","NJ")

我想从变量 age 中选择九个年龄值(您可以将其视为 age 在任何数据框中的列 age 采用从 0 到 90 的数值)。

    inlist(age,16, 24, 45, 54, 67,74, 78, 79, 85) 

问题:

age<-c(0:10) # for this problem age takes values from 0 to 10 only
data<-as.data.frame(age) # age is a variable of data frame data
data$m<-ifelse(c(1,7,9)%in%data$age,0,1) # generate a variable m which takes  value 0 if age is 1, 7, and 8 and 1, otherwise
Expected output: 
   age m
1    0 1
2    1 0
3    2 1
4    3 1
5    4 1
6    5 1
7    6 1
8    7 0
9    8 1
10   9 0
11  10 1

【问题讨论】:

  • 我相信您可能正在寻找match()%in%,但对Stata 的inlist 函数不太熟悉。
  • 如果您定义了stateage 并显示了预期的输出,这将有所帮助...
  • @Ananda 和@Ben:抱歉没有更明确。我现在已经编辑了这个问题,我希望它更清楚。
  • stata.com/help.cgi?inlist() 是更简洁直接的信息来源。在 Stata 中,inlist() 是一个函数,而不是一个命令。

标签: r command stata


【解决方案1】:

我想你想要%in%:

statevec <- c("NC","AZ","TX","NY","MA","CA","NJ")
state <- c("AZ","VT")
state %in% statevec ## TRUE FALSE
agevec <- c(16, 24, 45, 54, 67,74, 78, 79, 85) 
age <- c(34,45)
age %in% agevec ## FALSE TRUE

编辑:处理更新的问题。

从@NickCox 的链接复制:

inlist(z,a,b,...)
      Domain:       all reals or all strings
      Range:        0 or 1
      Description:  returns 1 if z is a member of the remaining arguments;
                        otherwise, returns 0.  All arguments must be reals
                        or all must be strings.  The number of arguments is
                        between 2 and 255 for reals and between 2 and 10 for
                        strings.

但是,我不太确定这与原始问题是否相符。我不太了解Stata,不知道z 是否可以是向量:听起来不是这样,在这种情况下,原始问题(将z=state 视为向量)没有意义。如果我们认为它可以是一个向量,那么答案就是as.numeric(state %in% statevec)——我想。

编辑:Ananda 更新

使用您更新的数据,这是一种方法,再次使用%in%

data <- data.frame(age=0:10)
within(data, {
    m <- as.numeric(!age %in% c(1, 7, 9))
})
   age m
1    0 1
2    1 0
3    2 1
4    3 1
5    4 1
6    5 1
7    6 1
8    7 0
9    8 1
10   9 0
11  10 1

通过使用! (NOT) 来反转%in% 的含义,这符合您的预期输出。这似乎与我的想法有点倒退(通常,0=FALSE="不在列表中"和 1=TRUE="在列表中")和我对 Stata 的阅读定义,但如果这是你想要的......

或者可以使用ifelse 以获得更多潜在的灵活性(即0/1 以外的值):在上面的代码中替换within(data, { m &lt;- ifelse(age %in% c(1, 7, 9),0,1)})

【讨论】:

  • @Ananda:我已经更新了这个问题。你能检查一下吗?
  • @BenBolker,对混乱的编辑感到抱歉!无法跟踪问题的所有编辑! ;)
  • @Ben,这是一个标量函数,可能有一个很好的理由:我不确定如何解释多对多匹配。 inlist( c(1,7,9),1) 应该评估为 TRUE 吗? inlist( c(1,7,9), c(9,7,1) ) 应该评估为 TRUE 吗?只有inlist( c(1,7,9), c(1,7,9), c(2,3,5) ) 评估为真吗?当在变量上下文中遇到inlist() 时(回想一下,Stata 仅适用于一个称为数据的矩形对象),它会针对数据集中的每个观察值进行评估。
  • 好吧,R 对其%in% 运算符使用了合理的定义(如果可能不是您想要的,也可能不完全等同于inline):c(1,7,9) %in% 1 给出TRUE FALSE FALSEc(1,7,9) %in% c(9,7,1) 给出TRUE TRUE TRUE(第一个操作数中的所有三个元素都匹配第二个操作数的元素)。我不知道有 >2 个参数的版本(%in% 只允许两个);我可能会将 R 定义为a %in% union(b,c,d,...)
  • @AnandaMahto:据我了解,as.numeric 生成 0 或 1。但是,ifelse 也允许其他值,例如 10 或 50。我想坚持使用 ifelse:within(data, { m &lt;- ifelse(age %in% c(1, 7, 9),0,1) })感谢您的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-17
  • 1970-01-01
  • 1970-01-01
  • 2018-11-13
  • 2021-02-14
  • 2014-11-27
相关资源
最近更新 更多