【问题标题】:Automatically creating derived variables in a dataframe [duplicate]在数据框中自动创建派生变量[重复]
【发布时间】:2013-01-04 16:53:17
【问题描述】:

可能重复:
Processing the list of data.frames with “apply” family of functions

我有一个包含六个数值变量 V1、V2、V3 和 V1.lag、V2.lag、V3.lag 的数据框。

注意:我的真实数据集有更多变量,但我仅使用 3 进行说明!

我希望能够自动(无需硬编码)运行所有 V 变量(不是滞后变量)并通过将每个 V 变量与对应的滞后变量相除来创建 V1.over.V1.lag 变量。

df<-data.frame(matrix(rnorm(216),72,6));
colnames(df) <- c("v1.raw", "v2.raw", "v3.raw", "v1.lag", "v2.lag", "v3.lag");

提前致谢

**编辑:我想出了如何识别“原始”列和“滞后”列**

raws <- sapply( names(df), function(x){ unlist(strsplit(x, "[.]"))[2] == "raw" } ); ## which are raw factors

lags <- sapply( names(df), function(x){ unlist(strsplit(x, "[.]"))[2] == "lag" } ); ## which are lagged factors

但我仍然不知道如何将所有原始因素与其滞后因素分开

which(raws);

会给我指数,但我如何将它们与滞后结合成新的因素?

df[which(raws)] / df[which(lags)]

没用

【问题讨论】:

  • 你试过什么?您可以将your previous question 中的答案扩展到此吗?你在哪里卡住?根据我的经验,如果您在寻求帮助之前与事物斗争一段时间,您将更快地学习 R 并最终获得更深入的理解。你向我们展示的战斗越多,我们就越愿意帮助我们!
  • 首先尝试更正您的问题的代码,尝试将您的 dd 更改为 df 并可能删除 dim1 和 dim2 列,这只是令人困惑。
  • 感谢您的评论。我编辑了主要问题以贡献我代码中唯一有效的部分

标签: r dataframe apply lapply sapply


【解决方案1】:

假设您的 data.frame 中只有 v.raw 和 v.lag 列,这应该可以工作

  mm <- colnames(df) <- c("v1.raw", "v2.raw", "v3.raw", "v1.lag", "v2.lag", "v3.lag")
  df[,gregexpr('.raw',mm) > 0] /df[,gregexpr('.*lag',mm) > 0]

编辑对解决方案的一些解释:

gregexpr('.raw',mm) > 0
[1]  TRUE  TRUE  TRUE FALSE FALSE FALSE  

head(df[,gregexpr('.raw',mm) > 0],1)
     v1.raw     v2.raw    v3.raw
1 0.7719037 -0.2078197 -1.223753

regexpr('.lag',mm) > 0
[1] FALSE FALSE FALSE  TRUE  TRUE  TRUE

head(df[,gregexpr('.lag',mm) > 0],1)
     v1.lag     v2.lag    v3.lag
1 0.7719037 -0.2078197 -1.223753

我们使用矢量化/ 进行除法,一次操作。

这里是一个例子:

df <- matrix(rep(c(1,2,3,4,5,6),each = 5),ncol=6)
colnames(df) <- c("v1.raw", "v2.raw", "v3.raw", "v1.lag", "v2.lag", "v3.lag")
    v1.raw v2.raw v3.raw v1.lag v2.lag v3.lag
[1,]      1      2      3      4      5      6
[2,]      1      2      3      4      5      6
[3,]      1      2      3      4      5      6
[4,]      1      2      3      4      5      6
[5,]      1      2      3      4      5      6


mm <- colnames(df)
df[,which(gregexpr('.raw',mm) > 0)] /df[,which(gregexpr('.lag',mm) > 0)]

   v1.raw v2.raw v3.raw      #as expected 1/4 2/5 3/6
[1,]   0.25    0.4    0.5 
[2,]   0.25    0.4    0.5
[3,]   0.25    0.4    0.5
[4,]   0.25    0.4    0.5
[5,]   0.25    0.4    0.5

Edit2用零阻止Nan

df <- matrix(rep(c(1,2,3,4,5,6),each = 5),ncol=6)
colnames(df) <- c("v1.raw", "v2.raw", "v3.raw", "v1.lag", "v2.lag", "v3.lag")
df[1,4] <- 0              ## I introduce a 0 here
mm <- colnames(df)
## I use ifelse , because it is vectorize also !
## If you find a 0 , don't compute , and retuen me the original value 
## You can do other things here 
ifelse(df[,which(gregexpr('.lag',mm) > 0)] != 0 ,
       df[,which(gregexpr('.raw',mm) > 0)] /df[,which(gregexpr('.lag',mm) > 0)],
       df[,which(gregexpr('.raw',mm) > 0)])  

    v1.lag v2.lag v3.lag    ## for some reasons ifelse choose other columns names!(lag not raw)
[1,]   1.00    0.4    0.5
[2,]   0.25    0.4    0.5
[3,]   0.25    0.4    0.5
[4,]   0.25    0.4    0.5
[5,]   0.25    0.4    0.5

【讨论】:

  • 对不起,我更新我的答案!
  • 谢谢,但这给出了一个数组 1,1,1,1,1,1,1,1,1,1
  • 和我上面的解决方案一样的问题
  • 它给你 1 因为你的 df.raw == df.lag,我在解决方案中添加了一些解释。希望这会有所帮助。
  • 多么愚蠢......谢谢一堆。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-27
  • 2021-11-19
  • 1970-01-01
  • 2017-11-12
  • 2014-10-06
相关资源
最近更新 更多