49

vars以下の最小限の例では、回帰式で文字列の値を使用しようとしています。ただし、変数名の文字列 ("v2+v3+v4") を式に渡すことしかできず、この文字列の本当の意味を渡すことはできません (たとえば、"v2" は dat$v2 です)。

回帰を実行するためのより良い方法があることは知っています (例: lm(v1 ~ v2 + v3 + v4, data=dat))。私の状況はもっと複雑で、数式で文字列を使用する方法を理解しようとしています。何かご意見は?

以下のコードを更新

# minimal example 
# create data frame
v1 <- rnorm(10)
v2 <- sample(c(0,1), 10, replace=TRUE)
v3 <- rnorm(10)
v4 <- rnorm(10)
dat <- cbind(v1, v2, v3, v4)
dat <- as.data.frame(dat)

# create objects of column names
c.2 <- colnames(dat)[2]
c.3 <- colnames(dat)[3]
c.4 <- colnames(dat)[4]

# shortcut to get to the type of object my full code produces
vars <- paste(c.2, c.3, c.4, sep="+")

### TRYING TO SOLVE FROM THIS POINT:
print(vars)
# [1] "v2+v3+v4"

# use vars in regression
regression <- paste0("v1", " ~ ", vars)
m1 <- lm(as.formula(regression), data=dat)

更新: @Arun はv1、最初の例の "" の欠落については正しかったです。これで私の例は修正されましたが、実際のコードにはまだ問題がありました。以下のコード チャンクでは、実際のコードをよりよく反映するように例を調整しました。問題は string にあると最初は考えて、より単純な例を作成することにしましたvars

うまくいかない例を次に示します:)dat上記で作成したものと同じデータ フレームを使用します。

dv <- colnames(dat)[1]
r2 <- colnames(dat)[2]
# the following loop creates objects r3, r4, r5, and r6
# r5 and r6 are interaction terms
for (v in 3:4) {
  r <- colnames(dat)[v]
  assign(paste("r",v,sep=""),r)
  r <- paste(colnames(dat)[2], colnames(dat)[v], sep="*")
  assign(paste("r",v+2,sep=""),r)
}

# combine r3, r4, r5, and r6 then collapse and remove trailing +
vars2 <- sapply(3:6, function(i) { 
                paste0("r", i, "+")
                })
vars2 <- paste(vars2, collapse = '')
vars2 <- substr(vars2, 1, nchar(vars2)-1)

# concatenate dv, r2 (as a factor), and vars into `eq`
eq <- paste0(dv, " ~ factor(",r2,") +", vars2)

問題は次のとおりです。

print(eq)
# [1] "v1 ~ factor(v2) +r3+r4+r5+r6"

regression最初の例とは異なりeq、列名 (例: ) は取り込まれませんv3。オブジェクト名 ( などr3) は保持されます。そのため、次のlm()コマンドは機能しません。

m2 <- lm(as.formula(eq), data=dat)
4

2 に答える 2

63

ここでいくつかの問題が発生しています。まず、これが問題を引き起こしているとは思いませんが、データ フレームを 1 つのステップで作成して、グローバル環境とデータ フレームの両方で浮遊v1する必要がないようにしましょう。v4次に、v2ここで因数を作成して、後で因数を作成する必要がないようにしましょう。

dat <- data.frame(v1 = rnorm(10),
                  v2 = factor(sample(c(0,1), 10, replace=TRUE)),
                  v3 = rnorm(10),
                  v4 = rnorm(10) )

パート 1さて、最初のパートとして、これはあなたが望むもののように見えます:

lm(v1 ~ v2 + v3 + v4, data=dat)

これを行う簡単な方法を次に示しますが、応答変数を指定する必要があります。

lm(v1 ~ ., data=dat)

または、貼り付けて関数を構築し、それを呼び出すこともできますlm

f <- paste(names(dat)[1], "~", paste(names(dat)[-1], collapse=" + "))
# "v1 ~ v2 + v3 + v4"
lm(f, data=dat)

ただし、これらの状況での私の好みはdo.call、関数に渡す前に式を評価する を使用することです。これにより、結果のオブジェクトが on のような関数を呼び出すのにより適したものになりますupdatecall出力の一部を比較します。

do.call("lm", list(as.formula(f), data=as.name("dat")))

パート 2 2番目のパートについては、これが目的のようです。

lm(factor(v2) + v3 + v4 + v2*v3 + v2*v4, data=dat)

まず、v2はデータ フレームの要素であるため、その部分は必要ありません。次に、算術演算を使用して相互作用を作成するための R の方法をより適切に使用することで、これをさらに単純化できます。

lm(v1 ~ v2*(v3 + v4), data=dat)

次に、paste;を使用して関数を作成するだけです。を使用したループはassign、より大きなケースであっても、おそらく良い考えではありません。

f <- paste(names(dat)[1], "~", names(dat)[2], "* (", 
           paste(names(dat)[-c(1:2)], collapse=" + "), ")")
# "v1 ~ v2 * ( v3 + v4 )"

lmその後、直接または を使用して呼び出すことができますdo.call

lm(f, data=dat)
do.call("lm", list(as.formula(f), data=as.name("dat")))

あなたのコードについてetcを使おうとしたときの問題は、値ではなく、r3変数の内容が欲しいということでした。値を取得するには、このように が必要です。次に、値を と一緒に折りたたみます。r3r3getpaste

vars <- sapply(paste0("r", 3:6), get)
paste(vars, collapse=" + ")

ただし、より良い方法はassign、次のように、必要な用語のベクトルを回避して構築することです。

vars <- NULL
for (v in 3:4) {
  vars <- c(vars, colnames(dat)[v], paste(colnames(dat)[2], 
                                          colnames(dat)[v], sep="*"))
}
paste(vars, collapse=" + ")

より R に似たソリューションは、次を使用することlapplyです。

vars <- unlist(lapply(colnames(dat)[3:4], 
                      function(x) c(x, paste(colnames(dat)[2], x, sep="*"))))
于 2013-06-10T14:34:52.753 に答える
6

TL;DR: を使用しますpaste

create_ctree <- function(col){
    myFormula <- paste(col, "~.", collapse="")
    ctree(myFormula, data)
}
create_ctree("class")
于 2016-11-08T14:51:42.740 に答える