R 表达式求值,字符串中的对象。。。还不清楚
我读过很多关于如何从字符串或求值表达式创建对象的主题,包括R 表达式求值,字符串中的对象。。。还不清楚,r,expression,evaluation,tidyverse,R,Expression,Evaluation,Tidyverse,我读过很多关于如何从字符串或求值表达式创建对象的主题,包括assign()、get()、as.name()或eval(substitute()),但有些事情我并不完全清楚 在我下面的示例中,我有一个输入数据集(长格式),我希望输出3个矩阵 输入数据帧: # Input dataframe df <- data.frame(v1 = c(rep("A", 3), rep("B", 3)), v2 = c(rep(letters[1:3], 2)),
assign()
、get()
、as.name()
或eval(substitute())
,但有些事情我并不完全清楚
在我下面的示例中,我有一个输入数据集(长格式),我希望输出3个矩阵
输入数据帧:
# Input dataframe
df <- data.frame(v1 = c(rep("A", 3), rep("B", 3)),
v2 = c(rep(letters[1:3], 2)),
dfA = sample(1:10, 6),
dfB = sample(1:10, 6),
dfC = sample(1:10, 6))
> df
v1 v2 dfA dfB dfC
1 A a 5 10 5
2 A b 4 7 9
3 A c 10 1 2
4 B a 7 9 7
5 B b 2 8 1
6 B c 9 3 4
因此,手动操作没有问题(我只是在这里执行第一个矩阵):
然后,我想将v1值放入row.names中:
row.names(get(paste0(dfName, "A"))) <- get(paste0(dfName, "A"))[, 1]
所以,我可以让它工作,但它不是“美丽”给我
是否有太多的assign()
或太多的eval(substitute())
?
这是做这件事的好方法吗
我想我几乎把手指放在它上面了,但我仍然不理解我可能会犯的错误
我错过什么了吗?有更好的方法吗?(所谓更好,我指的是清晰的编码、更好的效率、尊重R编码规则……)
非常感谢你的回答,很抱歉这篇长文章 1)映射通常,最好创建一个对象列表,因此使用末尾注释中的输入并使用xtabs
尝试此操作
没有使用任何软件包
fun <- function(nm) xtabs(df[c(nm, head(names(df), 2))])
L <- Map(fun, tail(names(df), -2))
names(L) <- sub("df", "", names(L)) # optional - remove "df" from names
2)重塑另一种可能性是通过将df
重塑为长形,然后在其上使用xtabs
来创建三维表格
长格式将为dfA
、dfB
和dfC
中的每个单元格提供一行,并新增两列:
- 新的
列包含原始“vnames”
、“dfA”
、“dfB”
列中的数值。“dfC”
和v.names
参数定义了这一点variable
- 新的
列标识“组”
列中的每个值来自哪个“vnames”
df列。
和timevar
参数定义了这一点times
选项卡[“B”,“B”,“C”]
,选项卡[,“B”,“C”]
,选项卡[“B”,“B”,“C”]
,选项卡[“B”,“C”]
,选项卡[,“B”,][/code>,选项卡[,“C”
没有使用任何软件包
vnames <- tail(names(df), -2) # c("dfA", "dfB", "dfC")
long <- reshape(df, dir = "long",
varying = vnames, v.names = "vnames",
times = sub("df", "", vnames), timevar = "Group")
tab <- xtabs(vnames ~ v1 + v2 + Group, long)
2a)重塑2::熔化此变体使用重塑2软件包中的melt
代替R底部的restrape
,并且更加紧凑:
library(reshape2)
xtabs(value ~ v1 + v2 + variable, data = melt(df))
注意:为再现性设置种子我们将此输入用作df
:
set.seed(123)
df <- data.frame(v1 = c(rep("A", 3), rep("B", 3)),
v2 = c(rep(letters[1:3], 2)),
dfA = sample(1:10, 6),
dfB = sample(1:10, 6),
dfC = sample(1:10, 6))
set.seed(123)
df1)映射通常最好创建一个对象列表,因此使用末尾注释中的输入并使用xtabs
尝试此操作
没有使用任何软件包
fun <- function(nm) xtabs(df[c(nm, head(names(df), 2))])
L <- Map(fun, tail(names(df), -2))
names(L) <- sub("df", "", names(L)) # optional - remove "df" from names
2)重塑另一种可能性是通过将df
重塑为长形,然后在其上使用xtabs
来创建三维表格
长格式将为dfA
、dfB
和dfC
中的每个单元格提供一行,并新增两列:
- 新的
“vnames”
列包含原始“dfA”
、“dfB”
、“dfC”
列中的数值。v.names
和variable
参数定义了这一点
- 新的
“组”
列标识“vnames”
列中的每个值来自哪个df列。timevar
和times
参数定义了这一点
这种方法的优点是易于查看所有切片。例如,请尝试以下各项:
选项卡[“B”,“B”,“C”]
,选项卡[,“B”,“C”]
,选项卡[“B”,“B”,“C”]
,选项卡[“B”,“C”]
,选项卡[,“B”,][/code>,选项卡[,“C”
没有使用任何软件包
vnames <- tail(names(df), -2) # c("dfA", "dfB", "dfC")
long <- reshape(df, dir = "long",
varying = vnames, v.names = "vnames",
times = sub("df", "", vnames), timevar = "Group")
tab <- xtabs(vnames ~ v1 + v2 + Group, long)
2a)重塑2::熔化此变体使用重塑2软件包中的melt
代替R底部的restrape
,并且更加紧凑:
library(reshape2)
xtabs(value ~ v1 + v2 + variable, data = melt(df))
注意:为再现性设置种子我们将此输入用作df
:
set.seed(123)
df <- data.frame(v1 = c(rep("A", 3), rep("B", 3)),
v2 = c(rep(letters[1:3], 2)),
dfA = sample(1:10, 6),
dfB = sample(1:10, 6),
dfC = sample(1:10, 6))
set.seed(123)
df您需要这些函数的标准评估版本:
assign(paste0(dfName, "A"), get(paste0(dfName, "A")) %>%
spread_(key = 'v2', value = paste0(dfName, "A")))
注意动词末尾的
,以及“v2”
被引用的事实
从dplyr
vignette:
标准评估基础
dplyr中使用NSE的每个函数都有一个使用SE的版本。
SE版本的名称始终是NSE名称,其上带有一个uu
结束。例如,summarise()的SE版本是summarise_();这个
arrange()的SE版本是arrange_u3;()。这些功能非常有效
与他们的NSE表亲类似,但他们的输入必须“引用”:
您需要这些函数的标准评估版本:
assign(paste0(dfName, "A"), get(paste0(dfName, "A")) %>%
spread_(key = 'v2', value = paste0(dfName, "A")))
注意动词末尾的
,以及“v2”
被引用的事实
从dplyr
vignette:
标准评估基础
dplyr中使用NSE的每个函数都有一个使用SE的版本。
SE版本的名称始终是NSE名称,其上带有一个uu
结束。例如,summarise()的SE版本是summarise_();这个
arrange()的SE版本是arrange_u3;()。这些功能非常有效
与他们的NSE表亲类似,但他们的输入必须“引用”:
我们可以通过data.table
中的dcast
转换为list
,而无需将多个列转换为value.var
library(data.table)
dcast(setDT(df), v1 ~v2, value.var = c("dfA", "dfB", "dfC"))
# v1 dfA_a dfA_b dfA_c dfB_a dfB_b dfB_c dfC_a dfC_b dfC_c
#1: A 3 8 4 6 9 5 7 6 1
#2: B 7 6 1 4 10 3 10 2 8
数据
set.seed(123)
df我们可以通过data.table
中的dcast
实现这一点,而无需将多个列转换为value.var
library(data.table)
dcast(setDT(df), v1 ~v2, value.var = c("dfA", "dfB", "dfC"))
# v1 dfA_a dfA_b dfA_c dfB_a dfB_b dfB_c dfC_a dfC_b dfC_c
#1: A 3 8 4 6 9 5 7 6 1
#2: B 7 6 1 4 10 3 10 2 8
数据
se
set.seed(123)
df <- data.frame(v1 = c(rep("A", 3), rep("B", 3)),
v2 = c(rep(letters[1:3], 2)),
dfA = sample(1:10, 6),
dfB = sample(1:10, 6),
dfC = sample(1:10, 6))
assign(paste0(dfName, "A"), get(paste0(dfName, "A")) %>%
spread_(key = 'v2', value = paste0(dfName, "A")))
library(data.table)
dcast(setDT(df), v1 ~v2, value.var = c("dfA", "dfB", "dfC"))
# v1 dfA_a dfA_b dfA_c dfB_a dfB_b dfB_c dfC_a dfC_b dfC_c
#1: A 3 8 4 6 9 5 7 6 1
#2: B 7 6 1 4 10 3 10 2 8
set.seed(123)
df <- data.frame(v1 = c(rep("A", 3), rep("B", 3)),
v2 = c(rep(letters[1:3], 2)),
dfA = sample(1:10, 6),
dfB = sample(1:10, 6),
dfC = sample(1:10, 6))