通过将函数应用于数据框的每一行来创建具有命名值的列表

时间:2015-04-07 20:57:13

标签: r

我试图通过将函数应用于数据框的每一行来获取每个元素都有名称的列表,但无法获得正确的输出。

假设这是我想要应用于每一行的函数:

format_setup_name <- function(m, v, s) {
 a <- list()
 a[[paste(m, "machines and", v, s, "GB volumes")]] <- paste(num_machines,num_volumes,vol_size,sep="-")
 a
}

如果这是输入数据框:

df <- data.frame(m=c(1,2,3), v=c(3,3,3), s=c(15,20,30))

我无法获得如下列表:

$`1-3-15`
[1] "1 machines and 3 15 GB volumes"

$`2-3-20`
[1] "2 machines and 3 20 GB volumes"

$`3-3-30`
[1] "3 machines and 3 30 GB volumes"

有人能给我提示怎么做吗?

为什么我需要这个?好吧,我想使用来自数据库的值来填充selectizeInput。由于我组合了多个列,因此我需要一种方法来将所选输入与值匹配。

2 个答案:

答案 0 :(得分:2)

这是setNames的一个很好的用例,它可以将names()属性添加到对象中。此外,如果您使用as.list,则只需一行即可完成此操作而无需任何循环:

setNames(as.list(paste(df$m, ifelse(df$m == 1, "machine", "machines"), "and", df$v, df$s, "GB volumes")), paste(df$m,df$v,df$s,sep="-"))
# $`1-3-15`
# [1] "1 machine and 3 15 GB volumes"
# 
# $`2-3-20`
# [1] "2 machines and 3 20 GB volumes"
# 
# $`3-3-30`
# [1] "3 machines and 3 30 GB volumes"

答案 1 :(得分:2)

托马斯已经为你的问题找到了一个非常巧妙的解决方案(在一行中也是如此!)。但我会告诉你如何能够成功地采用你最初尝试的方法:

# We'll use the same data, this time called "dat" (I avoid calling 
# objects `df` because `df` is also a function's name)
dat <- data.frame(m = c(1,2,3), v = c(3,3,3), s = c(15,20,30))

format_setup_name <- function(m, v, s) {
    a <- list() # initialize the list, all is well up to here

    # But here we'll need a loop to assign in turn each element to the list
    for(i in seq_along(m)) {
        a[[paste(m[i], v[i], s[i], sep="-")]] <- 
                   paste(m[i], "machines and", v[i], s[i], "GB volumes")
    }
    return(a)
}

请注意,括号内的内容是元素的名称,而<-右侧的内容是要分配的内容,而不是代码建议的反转内容。

让我们试一试:

my.setup <- format_setup_name(dat$m, dat$v, dat$s)

my.setup

# $`1-3-15`
# [1] "1 machines and 3 15 GB volumes"
#
# $`2-3-20`
# [1] "2 machines and 3 20 GB volumes"
#
# $`3-3-30`
# [1] "3 machines and 3 30 GB volumes"

一切似乎都很好。只需注意一点:使用$运算符,您需要使用单引号或双引号按名称访问单个项目:

my.setup$"1-3-15" # my.setup$1-3-15 won't work
# [1] "1 machines and 3 15 GB volumes"

my.setup[['1-3-15']] # equivalent
# [1] "1 machines and 3 15 GB volumes"

编辑:lapply版本

由于循环真的失宠了,这里有一个lapply的版本:

format_setup_name <- function(m, v, s) {
    a <- lapply(seq_along(m), function(i) paste(m[i], "machines and", v[i], s[i], "GB volumes"))
    names(a) <- paste(m, v, s, sep="-")
    return(a)
}