问题描述
我想将 5 个数据框中的所有数字(每个包含 3 列,1000 行)除以 5 个字符列表(1 个元素,1000 行)中的相应数字。例如:
Case
对于只有一列的数据框,我们可以这样做:
mylist1 <- list(A=c(1,3),B=c(1,1),C=c(0,2))
characterlist1 <- strrep(c("5","10"),1 )
(1) mylist1 CharacterList1 Output
A B C L -> A B C
1 1 0 5 -> .2 .2 0
3 1 2 10 -> .3 .1 .2
mylist2 <- list(A=c(0,B=c(2,2),C=c(1,1))
characterlist2 <- strrep(c("10",1 )
(2) mylist2 CharacterList2 Output
A B C L -> A B C
0 2 1 10 -> 0 .2 .1
1 2 1 10 -> .1 .2 .1
是否也有一种简单的方法可以对多列执行此操作?
我已经完成了 dividing columns in a list in R 并将我的数据框转换为一个大列表,我目前的解决方案是:
(3) for (j in 1:5) {
Y=get(paste0("DF",j))
Z=get(paste0("CharacterList",j))
Z <- as.numeric(Z)
Y <- as.vector(Y,mode = "numeric")
Q <- vector(mode = "numeric",length = length(Y))
for (i in 1:length(Y)) {Q[i] <- Z[i]/Y[i]}
但是,一旦我尝试将 (4) 的结果输入到 (3) 中,我就会收到“'list' 对象不能被强制输入'double'”错误。有什么我遗漏的吗?
解决方法
根据您的问题描述而不是(不匹配的)代码,您想要的是函数sweep
:
sweep(df,1L,numbers,`/`)
这将输入数据框中的每一列除以向量 numbers
。
需要
- 将每个数字列表转换为 data.frame(使用
as.data.frame
)。 - 将字符串转换为数字(使用
as.numeric
)。
如果您有多个 data.frames/number 向量,请通过 Map
执行上述操作:
Map(sweep,df_list,numbers_list,list(`/`))
注意这里如何将扫描函数 (/
) 放入单例列表中。这可以防止 Map
尝试将该函数视为要迭代的输入列表(这会失败)。相反,它现在看到一个包含单个元素的列表,因此它会回收其内容。边距参数 (1L
) 也会发生同样的情况。我们也可以将其放入单例列表中,但这不是必需的,因为 Map
自己注意到这不是列表输入,需要回收。
根据描述,我们可以循环遍历 list
的 data.frame
,并用向量的 unlist
ed list
划分每个数据集
lapply(lst_df,function(dat) dat/unlist(lst1))
,
获取列表中的所有 'mylist' 和 'characterlist' 并使用 Map
对它们进行计算。
list1 <- mget(ls(pattern = 'mylist\\d+'))
charvec1 <- mget(ls(pattern = 'characterlist\\d+'))
result <- Map(function(x,y) do.call(cbind,x)/as.numeric(y),list1,charvec1)
#$mylist1
# A B C
#[1,] 0.2 0.2 0.0
#[2,] 0.3 0.1 0.2
#$mylist2
# A B C
#[1,] 0.0 0.2 0.1
#[2,] 0.1 0.2 0.1