如何使用lapply或for循环将自定义函数应用于数据框指定列并获取正确结果
如何使用lapply或for循环将自定义函数应用于数据框指定列并获取正确结果
嗨,我来帮你搞定这个问题!你现在遇到的问题主要是函数和lapply的适配没做好,还有for循环的写法有误,咱们一步步拆解修正:
问题根源分析
- 函数与lapply的适配问题:你写的
group_maker1是按列索引设计的,但用lapply(obs[,1:3], group_maker1)时,传入函数的是每个列的向量值(比如day1列的c(1,0,1,0)),不是数字索引。这会导致obs[,x]出现无效索引,进而产生NA和错误结果。 - for循环写法错误:你在循环里重复定义函数完全没必要,而且没有初始化容器存储结果,自然看不到输出。
方法一:用lapply实现(更简洁)
先修正函数,让它直接接收单个day列的向量(而非索引),这样lapply可以直接遍历obs的列:
# 先保留你原有的数据定义 names <- c("A", "B", "C", "D") titles <- c("P", "S", "S", "P") day1 <- c(1,0,1,0) day2 <- c(0,0,1,1) day3 <- c(1,1,0,0) df <- data.frame(names, titles, day1, day2, day3) ids <- df[,1:2] obs <- df[,3:5] # 修正后的函数:接收单个day列的向量作为参数 group_maker_fixed <- function(day_col) { # 筛选当前day列值>0的行 selected_rows <- day_col > 0 # 提取对应行的names和titles g1 <- ids$names[selected_rows] g2 <- ids$titles[selected_rows] # 合并结果并去重 temp <- c(g1, g2) temp <- temp[!duplicated(temp)] return(temp) } # 用lapply遍历obs的所有列,生成结果列表 result_lapply <- lapply(obs, group_maker_fixed)
运行后查看结果,就能得到符合预期的输出:
> result_lapply $day1 [1] "A" "C" "P" "S" $day2 [1] "C" "D" "S" "P" $day3 [1] "A" "B" "P" "S"
方法二:用for循环实现(更直观)
如果更习惯用for循环,需要先初始化一个空列表存储结果,再遍历列索引调用修正后的函数:
# 初始化空列表,长度与obs的列数一致,命名和obs列名匹配 result_for <- vector("list", ncol(obs)) names(result_for) <- colnames(obs) # 遍历obs的列索引 for(i in seq_along(obs)) { # 调用函数,传入第i列的向量 result_for[[i]] <- group_maker_fixed(obs[,i]) }
运行后result_for和result_lapply的结果完全一致。
补充:保留原函数(按索引传参)的写法
如果你不想修改原函数,想让它继续接收列索引,那lapply需要遍历列索引而非列本身:
# 保留你原来的group_maker1函数 group_maker1 <- function(x){ g1 <- ids$names[obs[,x]> 0] g2 <- ids$titles[obs[,x]> 0] temp <- c(g1,g2) temp <- temp[!duplicated(temp)] paste(temp) } # 遍历obs的列索引(1到ncol(obs)) result_lapply_index <- lapply(1:ncol(obs), group_maker1) # 给列表添加列名,方便查看 names(result_lapply_index) <- colnames(obs)
这种写法也能得到正确结果,但第一种方法(让函数接收列向量)更符合lapply的使用习惯,代码可读性更强。
备注:内容来源于stack exchange,提问作者Looms
相关产品推荐
相关产品推荐

