我有一个名为factor_nonagg的data.frame,有50行和3列。我用参数因子写了一个函数category()。我正在对函数中的因素进行更改。当我将data.frame传递给此函数时,data.frame中没有进行任何更改。 有人可以帮助我对我的data.frame进行永久性更改吗?
n=50
category=function(factors){
for(i in 1:n){
if(factors[i,1]>=90) factors[i,1]<-2*.45
else if(factors[i,1]>=65) factors[i,1]<-1*.45
else factors[i,1]<-0
if(factors[i,2]>=.190) factors[i,2]<-2*.25
else if(factors[i,2]>=.140) factors[i,2]<-1*.25
else factors[i,2]<-0
if(factors[i,3]>=.03) factors[i,3]<-2*.30
else if(factors[i,3]>=.015) factors[i,3]<-1*.30
else factors[i,3]<-0
}}
category(factor_nonagg)
答案 0 :(得分:1)
R不容易支持函数的传递引用类型行为。当您对函数中的参数值进行更改时,将创建该对象的副本,并且只有在函数调用时,更改才会持续。
通常,您的函数会返回更改后的值(return(factor)
),并将新值分配给原始变量:
factor_nonagg <- category(factor_nonagg)
答案 1 :(得分:1)
循环遍历数据帧行将会非常缓慢。这是一种矢量化方法,在没有数据的情况下通常未经测试,但不会与dardisco提供的其他测试数据产生错误:
category=function(factors){
factors[[1]] <- 0.45*(0:2)[ findInterval(factors[[1]], c(-Inf, 65, 90, Inf) )]
factors[[2]] <- 0.25*(0:2)[ findInterval(factors[[2]], c(-Inf, 0.140, 0.190, Inf) )]
factors[[3]] <- 0.30*(0:2)[ findInterval(factors[[3]], c(-Inf, 0.015, 0.03, Inf) )]
return(factors) }
当然,与所有函数式语言一样,除了赋值命令外,不会修改factor_agg:
category(factor_agg) # no effect
factor_agg <- category(factor_agg) # replacement occurs.
findInterval
是一个非常有用的面向向量的函数,可用于返回分组值或使用,如本例所示,作为从一组字符或数值中选择的索引
答案 2 :(得分:0)
您需要在函数中设置一个输出对象,该对象返回您对df所做的更改。这可以通过添加
来实现return(factors)
就在函数定义中的最后一个大括号之前。
答案 3 :(得分:0)
你可以像这样接近它:
set.seed(1)
df1 <- data.frame(
f1 = sample(seq(150), size=50, replace=TRUE),
f2 = sample(seq(250) / 1000, size=50, replace=TRUE),
f3 = sample(seq(50) / 1000, size=50, replace=TRUE)
)
### vals1 = values
### mult1 = multiplier
fun1 <- function(x, vals1, mult1){
if (x >= max(vals1)) return(mult1*2)
if (x >= min(vals1) & x < max(vals1)) return(mult1)
return(0)
}
within(df1,
f1 <- sapply(f1, fun1, vals1=c(90, 65), mult1=0.45),
f2 <- sapply(f2, fun1, vals1=c(0.19, 0.14), mult1=0.25),
f3 <- sapply(f3, fun1, vals1=c(0.03, 0.15), mult1=0.3)
)
这避免了for
(虽然短循环不一定是坏事),节省打字并且如果你想改变值或乘数,它可以更容易推广。我在return
中使用fun1
,因为它有多个退出点。