以下の最小限の例では、文字列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
_で欠落している ""について正しいです。これは私の例を修正しましたが、実際のコードにはまだ問題がありました。以下のコードチャンクでは、実際のコードをよりよく反映するように例を適用しました。最初は問題が文字列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)
_
ここでいくつかの問題が発生しています。まず、これが問題を引き起こしているとは思いませんが、データフレームを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
を使用することです。これは、式を関数に渡す前に式を評価します。これにより、結果のオブジェクトはupdate
onなどの関数の呼び出しにより適したものになります。出力のcall
部分を比較します。
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")))
コードについてr3
などを使用しようとしたときに発生した問題は、値r3
ではなく、変数r3
の内容が必要なことでした。値を取得するには、このようにget
が必要です。次に、paste
とともに値を折りたたみます。
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="*"))))
TL; DR:paste
を使用します。
create_ctree <- function(col){
myFormula <- paste(col, "~.", collapse="")
ctree(myFormula, data)
}
create_ctree("class")