通过Sapply:Results aren';从子集上的函数创建多个变量;不是真的吗?

通过Sapply:Results aren';从子集上的函数创建多个变量;不是真的吗?,r,function,subset,sapply,R,Function,Subset,Sapply,导言 我有宽幅的纵向数据,衡量一家公司每年的总销售额。根据这一点,我想为数据中的每一年、每一家公司创建一组新的变量——市场份额。完整的数据集太大,无法以冗长而笨拙的方式完成此操作,因此我尝试使用sapply在子集(即标记每年销售数据的列)上运行函数 但是,结果似乎不会产生“真实”变量,因为它们在打印(head())中显示,但在现实中却不会显示(names())。我的代码有问题吗 # SAMPLE DATA agyrw <- structure(list(company = c(28, 12

导言

我有宽幅的纵向数据,衡量一家公司每年的总销售额。根据这一点,我想为数据中的每一年、每一家公司创建一组新的变量——市场份额。完整的数据集太大,无法以冗长而笨拙的方式完成此操作,因此我尝试使用sapply在子集(即标记每年销售数据的列)上运行函数

但是,结果似乎不会产生“真实”变量,因为它们在打印(
head()
)中显示,但在现实中却不会显示(
names()
)。我的代码有问题吗

# SAMPLE DATA
agyrw <- structure(list(company = c(28, 128, 22, 72, 62, 65, 132, 89, 46, 105), value.1993 = c(79272, 35850, 2124, 32, 0, 0, 0, 26359, 0, 0), value.1994 = c(103974, 10219, 31432, 0, 0, 0, 3997, 469, 0, 0)), .Names = c("company", "value.1993", "value.1994"), row.names = c(9L, 42L, 1L, 30L, 22L, 28L, 51L, 34L, 20L, 40L), class = "data.frame")

agyrw2 <- agyrw     # FOR A LATER COMPARISON

agyrw
#      company value.1993 value.1994
#         28      79272     103974
#        128      35850      10219
#         22       2124      31432
#         72         32          0
#         62          0          0
#         65          0          0
#        132          0       3997
#         89      26359        469
#         46          0          0
#        105          0          0
如何重写函数,使其在数据框中实际生成新列?

关于:

agyrw2 <- cbind(agyrw2,do.call(cbind, lapply(agyrw2[,2:3], function(x) {
    total <- sum(x)
    share <- as.numeric(format(round(x/total, 4), nsmall = 4))
    return(share)
    })))

agyrw2问题在于
share
实际上是一个两列矩阵,而不是两个单独的列。矩阵列的名称为
value.1993
value.1994
,但它仍然是一个对象

您可以在BaseR中执行此类操作,但对于数据挖掘和转换,最好使用专门为其设计的包之一

在dplyr中:

library(dplyr)
agyrw %>%
    mutate(share93=value.1993/sum(value.1993), share94=value.1994/sum(value.1994))
如果你有:


vars我在该代码中得到以下错误:
do.call(cbind,sappy(agyrw2[,2:3])函数(x){:第二个参数必须是一个列表
尝试通过
lappy()
更改
sapply()
这是可行的!但是出现了一个新问题;它重复了变量名:
names(agyrw2)[1]“公司”“value.1993”“value.1994”“1993年价值”“1994年价值”"
有没有办法在同一个函数中重命名第二个
值.1993
和第二个
值.1994
之类的东西,比如
共享.1993
/
共享.1994
吗?只是自动为新列指定唯一的名称,因为在实际的完整数据集中,大约有50个新列,所以我想在同一个函数中实现自动化。
mutate
代码可以工作,但是有没有办法在一吨列上自动运行它呢?完整的数据集包含50年的数据,这就是为什么我尝试在一个函数中与在子集上运行的
agyrw2[,2:3]
进行匹配,这真的很像
agyrw2[,2:51]
——这样我就不必笨拙地调整几十行代码。
names(agyrw)
#[1] "company"   "value.1993" "value.1994" "share.1993" "share.1994"
names(agyrw2)
#[1] "company"   "value.1993" "value.1994" "share"  
agyrw2 <- cbind(agyrw2,do.call(cbind, lapply(agyrw2[,2:3], function(x) {
    total <- sum(x)
    share <- as.numeric(format(round(x/total, 4), nsmall = 4))
    return(share)
    })))
agyrw2$share.1993 <- as.numeric(format(round(agyrw2$value.1993 / sum(agyrw2$value.1993), 4), nsmall = 4))
agyrw2$share.1994 <- as.numeric(format(round(agyrw2$value.1994 / sum(agyrw2$value.1994), 4), nsmall = 4))
library(dplyr)
agyrw %>%
    mutate(share93=value.1993/sum(value.1993), share94=value.1994/sum(value.1994))
vars <- names(agyrw[-1])
names(vars) <- paste0(vars, ".share")
agyrw %>% mutate_each_(funs(./sum(.)), vars)
library(sqldf)
names(agyrw) <- c("company", "value1993", "value1994")  # use syntactically valid SQL names
sqldf("select company, value1993, value1994,
              value1993/sum1993 as share1993,
              value1994/sum1994 as share1994
       from (agyrw join (
             select sum(value1993) as sum1993, sum(value1994) as sum1994 from agyrw))")