R语言data.frame中list列按指定索引逐行赋值实现方法
R数据框列表列逐行索引赋值实现
问题场景
现有如下结构的R数据框对象df:
df<-structure(list(tile_type_index = c(17L, 8L, 17L, 8L, 17L, 17L ), material_balance = list(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)), material_spend = c(0.333333333333333, 0.333333333333333, 0.333333333333333, 0.333333333333333, 0.333333333333333, 0.333333333333333)), row.names = c("71", "81", "71.1", "81.1", "71.2", "71.3"), class = "data.frame")
直接打印df的输出为:
tile_type_index 71 17 81 8 71.1 17 81.1 8 71.2 17 71.3 17 material_balance 71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 71.1 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 81.1 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 71.2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 71.3 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 material_spend 71 0.3333333 81 0.3333333 71.1 0.3333333 81.1 0.3333333 71.2 0.3333333 71.3 0.3333333
需要实现逐行处理逻辑:将每行的material_spend值,赋值给该行material_balance列表元素中索引等于tile_type_index的位置,等价于逐行执行material_balance[tile_type_index] <- material_spend的操作。
处理后的预期输出如下:
tile_type_index 71 17 81 8 71.1 17 81.1 8 71.2 17 71.3 17 material_balance 71 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.33, 0, 0, 0 81 0, 0, 0, 0, 0, 0, 0, 0.33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 71.1 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.33, 0, 0, 0 81.1 0, 0, 0, 0, 0, 0, 0, 0.33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 71.2 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.33, 0, 0, 0 71.3 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.33, 0, 0, 0 material_spend 71 0.3333333 81 0.3333333 71.1 0.3333333 81.1 0.3333333 71.2 0.3333333 71.3 0.3333333
实现方法
- base R 向量化方案(性能最优)
用Map函数做行级映射,无需显式循环,直接赋值回原列即可:
df$material_balance <- Map( function(balance_vec, target_idx, assign_val) { balance_vec[target_idx] <- assign_val balance_vec }, df$material_balance, df$tile_type_index, df$material_spend )
- for循环方案(逻辑最直观)
逐行遍历修改,注意访问列表列元素必须使用双中括号[[:
for (row_i in seq_len(nrow(df))) { df$material_balance[[row_i]][df$tile_type_index[row_i]] <- df$material_spend[row_i] }
- dplyr 语法方案
如果使用tidyverse生态,可通过rowwise逐行处理:
library(dplyr) df <- df %>% rowwise() %>% mutate( material_balance = list({ temp_vec <- material_balance temp_vec[tile_type_index] <- material_spend temp_vec }) ) %>% ungroup()
内容的提问来源于stack exchange,提问作者locket
相关产品推荐
相关产品推荐

