首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >r:使用`for`和`if`仅在数值变量上运行run函数

r:使用`for`和`if`仅在数值变量上运行run函数
EN

Stack Overflow用户
提问于 2019-02-28 02:25:34
回答 2查看 156关注 0票数 1

我有一个包含datevar1_sharevar2_sharetotal的四列数据帧。我只想将每个share指标与total相乘,以创建包含var1var2的原始值的新变量。请参见下面的代码(有点冗长),以构造包含共享变量的数据帧:

代码语言:javascript
复制
df<- data.frame(dt= seq.Date(from = as.Date('2019-01-01'), 
    to= as.Date('2019-01-10'), by= 'day'),
    var1= round(runif(10, 3, 12), digits = 1), 
    var2= round(runif(10, 3, 12), digits = 1))
df$total<- apply(df[2:3], 1, sum)
ratio<- lapply(df[-1], function(x) x/df$total)
ratio<- data.frame(ratio)
df<- cbind.data.frame(df[1],ratio)
colnames(df)<- c('date', 'var1_share', 'var2_share', 'total')
df

最终的数据帧应如下所示:

代码语言:javascript
复制
> df
date var1_share var2_share total
1  2019-01-01  0.5862069  0.4137931     1
2  2019-01-02  0.6461538  0.3538462     1
3  2019-01-03  0.3591549  0.6408451     1
4  2019-01-04  0.7581699  0.2418301     1
5  2019-01-05  0.3989071  0.6010929     1
6  2019-01-06  0.5132743  0.4867257     1
7  2019-01-07  0.5230769  0.4769231     1
8  2019-01-08  0.4969325  0.5030675     1
9  2019-01-09  0.5034965  0.4965035     1
10 2019-01-10  0.3254438  0.6745562     1

我在for循环中嵌套了一条if语句,希望返回一个名为share的新数据帧。我希望它在使用share变量时跳过date,因为我已经合并了is.numeric,所以它忽略了date,但是,当我运行它时,它只返回日期,而不返回所需的日期结果、每个变量的份额(作为单独的列)和总计列。请参见以下代码:

代码语言:javascript
复制
for (i in df){
  share<- if(is.numeric(i)){
     i * df$total
    } else i
  share<- data.frame(share)
  return(share)
}
share

> share
share
1  2019-01-01
2  2019-01-02
3  2019-01-03
...

如何调整此函数,使share返回包含日期、变量1和2的原始变量以及合计的数据帧?

EN

回答 2

Stack Overflow用户

发布于 2019-02-28 03:21:50

可以注意到,将向量(*)与data.frame相乘将在数据帧上强制转换乘法(将列1、2、3上的向量相乘,等等)。因此,您可以在不使用任何“apply”的情况下完成此操作,只需使用total列和要乘以的列的*即可。

或者,您可以创建一个简单的函数来实现此结果。下面就是这样一个例子。

代码语言:javascript
复制
Multi_share <- function(x, total_col = "total"){
  if(is.character(total_col))
    return(x[,sapply(x, is.numeric)[names(x) != total_col]] * x[, total_col])
  if(is.numeric(total_col) && NROW(total_col) == NROW(x))
    return(x[,sapply(x, is.numeric)] * total_col)
  stop("Total unrecognized. Must either be a 1 dimensional vector, a column matrix or a character specifying the total column in R.")
}
cbind(df, Multi_share(df))

还可以更改列的名称。

票数 2
EN

Stack Overflow用户

发布于 2019-02-28 03:03:44

也许你想要这样的东西?

代码语言:javascript
复制
share <-df[, sapply(df,is.numeric)]
share <-mapply(function(x) x*share$total, share[,names(share)!="total"])

第一行将只返回数字列(因此过滤了日期)。第二个将乘以每一列(除total之外)和total。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54912170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档