我有这个数据帧:
df <- data.frame (
A = c("ABC11234","ABC11"),
B = c(11,1),
C = c("11",11),
D = c(11.1,"11.1"))
我应用这个函数来告诉我哪些行和列有这个确切的字符串,并将输出分配给"a">
a<- lapply(df, function(x) grep("^11$",x))
现在我得到了一个列表,我想:
- 提取对(column[name]和row[value](,这样我就可以确切地知道哪一列、哪一行有我在lapply中查找的确切字符串
在上面使用grep的DF示例中,我想知道B=1和C=1,2(例如,列B/行1和列C/行1以及行2的值为"^11$"(
我试过做一些类似于a==integer(0(或unlist(a(的事情,但我被卡住了。
在我看来,您想要的输出只是那些列中包含您想要的"字符串"目前还不清楚是否要避免包含数字11
,因为字符串函数会将数字强制转换为字符串。然而,这是我的解决方案,我使用了stringr
包而不是基本包。我首先提取所有满足正则表达式的元素(即整个"字符串"是"11"
(
library(stringr)
d <- lapply(df, function(x) str_extract_all(x,"^11$"))
这将生成一个长度等于数据帧的列数的列表。列表中的每个元素具有与列中的行相同数量的元素,并且是"11"
或character(0)
。现在,我们获取列表中满足长度大于0的条件的所有元素的索引(即,您想要的字符串至少在列中出现一次(。
lapply(d, function (x) which(x>0))
这将生成另一个长度为4的列表。每个元素都是一个向量,包含满足条件的每列的行#。
让我们取消列出此
e <- unlist(lapply(d, function (x) which(x>0)))
这将生成一个命名向量,其中向量中的项目是行号,名称是列:
B C1 C2
2 1 2
为了消除重复的列名(C1、C2等(,我们将再执行一个字符串函数,用列名替换后面跟着字母的任何列名:
names(e) <- str_replace_all(names(e),"([A-Z])\d","\1")
e
的输出为:
B C C
1 1 2
所有代码加在一起:
library(stringr)
d <- lapply(df, function(x) str_extract_all(x,"^11$"))
lapply(d, function (x) which(x>0))
e<- unlist(lapply(d, function (x) which(x>0)))
names(e) <- str_replace_all(names(e),"([A-Z])\d","\1")
e
还有一个选项是将其重塑为"long"格式,然后获得相应的列名
library(dplyr)
library(tidyr)
library(stringr)
df %>%
mutate(across(everything(), as.character), row = row_number()) %>%
pivot_longer(cols = -row, names_to = 'col') %>%
group_by(row) %>%
summarise(col = unique(col[str_detect(value, '^11$')]), .groups = 'drop')
# A tibble: 3 x 2
# row col
# <int> <chr>
#1 1 B
#2 1 C
#3 2 C
我不确定你是否想要下面的
a <- transform(
as.data.frame(
which(matrix(grepl("^11$", as.matrix(df)), nrow = nrow(df)),
arr.ind = TRUE
)),
col = names(df)[col]
)
它给出
> a
row col
1 1 B
2 1 C
3 2 C
我建议使用lapply()
:
#Data
df <- data.frame (
A = c("ABC11234","ABC11"),
B = c(11,1),
C = c("11",11),
D = c(11.1,"11.1"),stringsAsFactors = F)
#List
a<- lapply(df, function(x) grep("^11$",x))
#List 2
a[lapply(a,length)==0]
输出:
$A
integer(0)
$D
integer(0)
如果你想从df
中提取这些值,你可以这样做:
df[,rownames(do.call(rbind,a[lapply(a,length)==0]))]
输出:
A D
1 ABC11234 11.1
2 ABC11 11.1