R 从全局环境中的对象获取colnames(使用特定模式),然后只返回';这是新的
所以我有一堆中间数据帧对象,它们在我的全局环境中按照顺序编号。i、 e.IRIS1\u St、IRIS2\u Db、IRIS1\u Start、IRIS2\u FIXAR、IRIS4\u Change、IRIS10\u 我已经解决了如何提取这些内容并返回行数和列数,而不保留列表列(见下文),从技术上讲,我已经提取了列名。但是,我一辈子都无法解决如何将这个colname列转换为非列表的列,这样我就可以比较滞后值并返回一个更简单的列来显示新内容。我尝试了data.table()、data.frame()、as.character()和str_replace_all()将其转换为向量。但似乎什么都不管用,这似乎是因为我不善于使用列表R 从全局环境中的对象获取colnames(使用特定模式),然后只返回';这是新的,r,string,dplyr,purrr,stringr,R,String,Dplyr,Purrr,Stringr,所以我有一堆中间数据帧对象,它们在我的全局环境中按照顺序编号。i、 e.IRIS1\u St、IRIS2\u Db、IRIS1\u Start、IRIS2\u FIXAR、IRIS4\u Change、IRIS10\u 我已经解决了如何提取这些内容并返回行数和列数,而不保留列表列(见下文),从技术上讲,我已经提取了列名。但是,我一辈子都无法解决如何将这个colname列转换为非列表的列,这样我就可以比较滞后值并返回一个更简单的列来显示新内容。我尝试了data.table()、data.frame
library(dplyr)
library(purrr)
library(stringr)
IRIS1_St <- iris
IRIS2_Db <- IRIS1_St %>%
mutate(Petal.Length2 = Petal.Length*2)
IRIS3_Sum <- IRIS2_Db %>%
mutate(Sepal.sum = sum(Sepal.Length, Sepal.Width))
IRIS4_Change <- IRIS3_Sum %>%
mutate(SL.Change = Sepal.Length - lag(Sepal.Length)) %>% filter(Petal.Length >=4)
IRIS10_bananas <- IRIS4_Change %>% mutate( bananas = case_when(Sepal.Length >6 ~ "BANANAS!!"))
Obj_Size <- grep("^IRIS",names(.GlobalEnv),value=TRUE) %>%
na.omit() %>%
mget(envir = globalenv()) %>%
{OS <<-.} %>%
map_df(nrow) %>%
pivot_longer(1:max(ncol(.)), names_to = "Obj_name", values_to = "nrow") %>%
left_join(OS %>%
map_df(ncol) %>%
pivot_longer(1:max(ncol(.)), names_to = "Obj_name", values_to = "ncol")
) %>%
data.frame(OS %>%
lapply(colnames) %>%
data.table()) %>%
mutate(number = as.numeric(replace_na(str_extract(Obj_name, "(?i)(?<=IRIS\\D{0,1})\\d+"), 0))) %>%
arrange(number, Obj_name) %>%
select(-number) %>% data.frame() %>%
rename(colnames = '.')
#just to seperate out the colname extraction I've done so far
OST <- OS %>% lapply(colnames) %>% data.table()
我使用下面akrun的建议重写了上述内容
library(dplyr)
library(purrr)
library(stringr)
library(tibble)
Obj_Size <- grep("^IRIS",names(.GlobalEnv),value=TRUE) %>% #ID all objects in GE starting with "IRIS"
na.omit() %>%
mget(envir = globalenv()) %>% #Use base R to get them
{OS <<-.} %>% #create intermediate object in GE to join to later
map_df(nrow) %>% #Map nrow using purrr
pivot_longer(1:max(ncol(.)), names_to = "Obj_name", values_to = "nrow") %>% #pivot so it's readable
left_join(OS %>% #repeat with ncol and join back to dataset
map_df(ncol) %>%
pivot_longer(1:max(ncol(.)), names_to = "Obj_name", values_to = "ncol")
) %>%
left_join(OS %>% #repeat with colnames
map(colnames) %>%
enframe() %>% #create 2 col dataframe
rename(Obj_name = name,
colnames = value)) %>%
mutate(number = as.numeric(replace_na(str_extract(Obj_name, "(?i)(?<=IRIS\\D{0,1})\\d+"), 0))) %>% #extract number after IRIS in object name so we can order correctly even when we get to 10 as when ordered by name with 10 it puts it after 1.
arrange(number, Obj_name) %>%
select(-number) %>%
data.frame() %>%
mutate (new_col = map2_chr(colnames, lag(colnames), ~toString(setdiff(.x, .y)))) #Id changes between colnames and only return anything new.
库(dplyr)
图书馆(purrr)
图书馆(stringr)
图书馆(tibble)
Obj_Size%#标识GE中以“IRIS”开头的所有对象
na.省略()%>%
mget(envir=globalenv())%>%#使用base R获取它们
{OS%#使用purrr映射nrow
pivot_更长(1:max(ncol(.)),名称为“\u to=”Obj_name”,值为“\u to=”nrow”)%>%#pivot,因此它是可读的
左_连接(OS%>%#使用ncol重复并连接回数据集
map_df(ncol)%>%
pivot_更长(1:max(ncol(.)),名称到=“Obj_name”,值到=“ncol”)
) %>%
左_连接(OS%>%#用colnames重复
映射(colnames)%%>%
enframe()%>%#创建2列数据帧
重命名(对象名称=名称,
colnames=value))%>%
mutate(number=as.numeric(replace_na)(str_extract(Obj_name),(?我们可以使用map2
执行setdiff
,在这里通过比较list
列与list
列的lag
来返回list
列
library(dplyr)
library(purrr)
Obj_Size %>%
mutate(new_col = map2(colnames, lag(colnames), setdiff), colnames = NULL)
-输出
# Obj_name nrow ncol new_col
#1 IRIS1_St 150 5 Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species
#2 IRIS2_Db 150 6 Petal.Length2
#3 IRIS3_Sum 150 7 Sepal.sum
#4 IRIS4_Change 89 8 SL.Change
#5 IRIS10_bananas 89 9 bananas
# Obj_name nrow ncol new_col
#1 IRIS1_St 150 5 Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species
#2 IRIS2_Db 150 6 Petal.Length2
#3 IRIS3_Sum 150 7 Sepal.sum
#4 IRIS4_Change 89 8 SL.Change
#5 IRIS10_bananas 89 9 bananas
如果需要是字符
列,请使用
library(stringr)
Obj_Size %>%
mutate(new_col = map2_chr(colnames, lag(colnames),
~ str_c(setdiff(.x, .y), collapse=", ")), colnames = NULL)
-输出
# Obj_name nrow ncol new_col
#1 IRIS1_St 150 5 Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species
#2 IRIS2_Db 150 6 Petal.Length2
#3 IRIS3_Sum 150 7 Sepal.sum
#4 IRIS4_Change 89 8 SL.Change
#5 IRIS10_bananas 89 9 bananas
# Obj_name nrow ncol new_col
#1 IRIS1_St 150 5 Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species
#2 IRIS2_Db 150 6 Petal.Length2
#3 IRIS3_Sum 150 7 Sepal.sum
#4 IRIS4_Change 89 8 SL.Change
#5 IRIS10_bananas 89 9 bananas
或者使用base R
和Map
Obj_Size$new_col <- Map(setdiff, Obj_Size$colnames, c(NA, head(Obj_Size$colnames,-1)))
Obj\u Size$new\u col因为您在colnames
中有一个列表,所以您可以使用map
的purrr
变体:
library(dplyr)
library(purrr)
Obj_Size %>%
mutate(new_col = map2_chr(colnames, lag(colnames), ~toString(setdiff(.x, .y))))
其中,新列
如下所示:
# new_col
#1 Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species
#2 Petal.Length2
#3 Sepal.sum
#4 SL.Change
#5 bananas
在base R中,您可以使用mapply
:
Obj_Size$new_col <- mapply(function(x, y) toString(setdiff(x, y)),
Obj_Size$colnames, c(NA, Obj_Size$colnames[-nrow(Obj_Size)]))
Obj\u Size$new\u col非常感谢您的解决方案,您和akrun都有类似的解决方案,您能解释~toString()参数吗?toString
为传递的向量创建一个逗号分隔的值。请参见示例toString(c('this','is','a','text'))
等效于paste0(..,collapse=','
Ahh好的,我从来没有从paste0分支出来过!你认为我使用Lappy获取colnames有一个purr解决方案吗?我不知道如何在那个特定场景中使用map。@Medwards只需做map(OS,colnames)
@Medwards如果需要两列数据集,map(OS,colnames)%%>%enframe
完美!我在最后重新编写了代码,以考虑这些评论,谢谢!