搜索一段时间后,找不到平滑的R形解决方案。
我有一个向量列表,我想将其转换为数据帧并添加带有向量名称的列。我不能使用cbind()和melt()到单个数据框b / c来做到这一点,其中存在具有不同行数的向量。
基本示例为:
list<-list(a=c(1,2,3),b=c(4,5,6,7))
var<-"group"
我想出并起作用的是:
list<-lapply(list, function(x) data.frame(num=x,grp=""))
for (j in 1:length(list)){
list[[j]][,2]<-names(list[j])
names(list[[j]])[2]<-var
}
但是我试图更好地使用lapply()并拥有更简洁的编码实践。现在,我非常依赖for和if语句,许多基本函数已经执行了它们,并且比现在的代码效率更高。
我想要的伪代码类似:
list<-lapply(list, function(x) data.frame(num=x,get(var)=names(x))
有没有一种干净的方法可以做到这一点?
第二个密切相关的问题,如果我已经有了一个数据框列表,为什么使用lapply()重新分配列值和名称如此困难?
所以使用类似的东西:
list<-list(a=data.frame(num=c(1,2,3),grp=""),b=data.frame(num=c(4,5,6,7),grp=""))
var<-"group"
#pseudo code
list<-lapply(list, function(x) x[,2]<-names(x)) #populate second col with name of df[x]
list<-lapply(list, function(x) names[[x]][2]<-var) #set 2nd col name to 'var'
伪代码的第一行引发有关匹配行长度的错误。为什么lapply()不仅会循环并像在单个数据帧上的相同函数一样重复name(x)会在for循环中发生?
对于第二行,据我了解,我可以使用setNames()重新分配所有列名,但是如何仅对其中一个列名进行这项工作呢?
非常感谢您提出的任何想法或指向涵盖此主题并帮助我理解lapply()在这种情况下的行为的其他线索。
答案 0 :(得分:3)
不使用循环的完整R基础方法
List<IFruitPayment> fruitPayments = new ArrayList<>():
fruitPayments.add(new FruitUnit());
fruitPayments.add(new FruitVolume());
fruitPayments.add(new FruitWeight());
for(IFruitPayment payment:fruitPayments) {
System.out.println(payment.payFruit());
}
答案 1 :(得分:1)
关于第一个/主要问题,您可以为此使用软件包enframe
中的函数tibble
library(tibble)
library(tidyr)
library(dplyr)
l<-list(a=c(1,2,3),b=c(4,5,6,7))
l %>%
enframe(name = "group", value="value") %>%
unnest(value) %>%
group_split(group)
答案 2 :(得分:0)
尝试一下:
library(dplyr)
mylist <- list(a = c(1,2,3), b = c(4,5,6,7))
bind_rows(lapply(names(mylist), function(x) tibble(grp = x, num = mylist[[x]])))
# A tibble: 7 x 2
grp num
<chr> <dbl>
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
6 b 6
7 b 7
这本质上是一个基于lapply
的解决方案,在该解决方案中,您遍历列表的名称,而不是单个列表元素本身。如果您喜欢在R底下做所有事情,请注意上面的内容等同于
do.call(rbind, lapply(names(mylist), function(x) data.frame(grp = x, num = mylist[[x]], stringsAsFactors = F)))
已经说过,tibble
是data.frames的现代实现方式,它是首选的,与bind_rows
构造相比,do.call(rbind...
是首选。
关于第二个问题,请注意以下几点:
lapply(mylist, function(x) str(x))
num [1:3] 1 2 3
num [1:4] 4 5 6 7
....
lapply(mylist, function(x) names(x))
$a
NULL
$b
NULL
您在这里看到的是lapply
内的函数获取mylist
的元素。在这种情况下,可以使用数字矢量。就lapply
内部调用的函数而言,它没有任何名称。要强调这一点,请考虑以下因素:
names(c(1,2,3))
NULL
是相同的:向量c(1,2,3)
没有名称属性。