【问题标题】:For Loop conversion to apply/plyrFor 循环转换为 apply/plyr
【发布时间】:2016-08-24 15:00:14
【问题描述】:

我已经编写了以下代码,并希望通过使用 plyr 或 apply 来改进它,可惜我似乎无法让它工作。这个想法是识别正确的列,然后提取/获取适当的值。

df <- data.frame(ID=c(1,2,3,4,5),COUNTRY=c('NL','FR','NL','BE','NL'),
             NL_GEN=c(5,5,10,20,5),FR_GEN=c(15,10,10,25,5),BE_GEN=c(10,10,5,15,5))

col_sel <- vector('numeric',length=nrow(df))
for ( i in 1:nrow(df)) {
  col_sel[i] <- as.numeric(df[i,grep(paste(df$COUNTRY[i],"_GEN",sep = ""),names(df))])
}

如何使用 plyr 或 apply 一次通过 1 行并返回单个值而不是整个列?

感谢您提供的任何帮助。

【问题讨论】:

    标签: r for-loop apply plyr


    【解决方案1】:

    考虑vapply()seq_along(),它允许您指定输出,这里是一个数字向量:

    new_col_sel <- vapply(seq_along(df), function(i) {
          df[i, grep(paste0(df$COUNTRY[i], "_GEN"), names(df))]
    }, numeric(1))
    
    new_col_sel   
    # [1]  5 10 10 15  5
    
    all.equal(col_sel, new_col_sel)
    # [1] TRUE 
    

    如果需要向数据框添加一列,只需分配它:

    df$col_sel <- vapply(seq_along(df), function(i) {
         df[i, grep(paste0(df$COUNTRY[i], "_GEN"), names(df))]
    }, numeric(1))
    
    #   ID COUNTRY NL_GEN FR_GEN BE_GEN col_sel
    # 1  1      NL      5     15     10       5
    # 2  2      FR      5     10     10      10
    # 3  3      NL     10     10      5      10
    # 4  4      BE     20     25     15      15
    # 5  5      NL      5      5      5       5
    

    【讨论】:

    • 谢谢,代码不能完全在我的完整数据集上运行,给出错误“vapply 中的错误............值必须是类型'double'......”到期事实上,数字存储为文本,但很容易修复。
    【解决方案2】:

    我认为我们可以使用 plyr 包中的 adply

    library(plyr)
    adply(df, 1, function(x) c(Result = x[,which(grepl(x$COUNTRY, names(x)))]))
    
    #   ID COUNTRY NL_GEN FR_GEN BE_GEN Result
    # 1  1      NL      5     15     10      5
    # 2  2      FR      5     10     10     10
    # 3  3      NL     10     10      5     10
    # 4  4      BE     20     25     15     15
    # 5  5      NL      5      5      5      5
    

    【讨论】:

    • 嗨,我收到以下错误“list_to_dataframe(res, attr(.data, "split_labels"), .id, id_as_factor) 中的错误:结果必须是原子的,或者所有的数据帧”。我认为它必须与 COUNTRY 是 char 相关,因为我已将它们更正为所有数字......仍然无法正常工作:/
    • @Voltorr 这听起来像是您的数据有问题,您是否有比 *_GEN 更多的包含国家名称的列?
    猜你喜欢
    • 2017-06-02
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多