r - 具有某些条件的 data.frame 中字符单元格的组合
问题描述
我希望有人可以帮助我解决这个问题。想象以下字符数据框:
df <- data.frame(X1=c("a", "b"), X2=c("k", "l"))
df
X1 X2
1 a k
2 b l
我想获得列的单元格之间的所有可能组合。
在这种情况下:
ak
人
bk
bl
我的问题是我不想指定我有多少列和行,并且代码应该忽略 NA(缺失值)。编辑:所以在三列中必须有三个元素。
df <- data.frame(X1=c("a", "b", "NA", "NA"), X2=c("k", "l", "m", "NA"), X3=c("e", "t", "l", "p"))
df
X1 X2 X3
1 a k e
2 b l t
3 NA m l
4 NA NA p
另一个问题是,我不想要长度小于列数的组合。因此,请确定一些适合的示例:
阿克
麦酒
blt
一些不适合的例子:
人
呐呐
然后应将结果保存在字符向量中。向量中的每个元素都应该是一个组合。
也许有人有一个想法,或者可能已经有一个线程可以帮助我,但我没有找到一些。
我已经尝试过不同的函数,比如 combn() 或 combine() 但要么它不适合这个问题,要么我以错误的方式使用它。
编辑:第二个df的整个假定输出:
阿克
akt
akl
akp
麦酒
alt
全部
阿尔卑斯山
AME
上午
反洗钱
放大器
bke
bkt
bkl
bkp
布尔
blt
比尔
blp
bme
bmt
bml
bmp
我希望我没有犯错。
解决方案
data.frame 中组合的 R 基函数是expand.grid
.
expand.grid(df)
X1 X2 X3
1 a k e
2 b k e
3 NA k e
4 NA k e
... <lines removed for brevity>
61 a NA p
62 b NA p
63 NA NA p
64 NA NA p
您提供的示例数据的问题是它没有任何NA
值。创建 时data.frame
,将文本“NA”放在引号中,这告诉 R 中的每一列都df
应该包含一个字符向量,其元素等于字母“N”,后跟字母“A”,而不是 R 的缺失值数据,NA
(更准确地说,每一列都是一个factor
(枚举vector
,请参阅 R 帮助中的 ?factor),包括一个级别“NA”(一个字符向量,包含字母“N”后跟字母“A” ) 而不是 的级别NA
,但我离题了...查看factorsAsStrings
R 帮助中的论点?data.frame
-- 以及下面的主题以 ?factors
获取更多信息。)
底线:要使用factor
包含NA
值的列创建 data.frame,请不要在 周围使用引号NA
:
df_NAs <- data.frame(X1=c("a", "b", NA, NA), X2=c("k", "l", "m", NA), X3=c("e", "t", "l", "p"))
现在,为了解决您的问题,我们需要NA
在df_NAs
调用expand.grid
. 记住 Rdata.frame
继承自(list
换句话说,R data.frame是一个列表,其中列表的每个元素包含一列向量。结果将作为向量列表返回:data.frame
lapply
data.frame
na.omit
NA
list_NoNAs <- lapply(df_NAs, na.omit)
list_NoNAs
$X1
[1] a b
attr(,"na.action")
[1] 3 4
attr(,"class")
[1] "omit"
Levels: a b
$X2
[1] k l m
attr(,"na.action")
[1] 4
attr(,"class")
[1] "omit"
Levels: k l m
$X3
[1] e t l p
Levels: e l p t
通过查看列表中每个项目的第一行,您可以看到NA
s 已被删除。列表中每个元素的长度可以显示为:
lapply(list_NoNAs, length)
$X1
[1] 2
$X2
[1] 3
$X3
[1] 4
所以现在你有不同长度的 a ,list
因为从.vectors
NA
data.frame
幸运的是,expand.grid
不仅在data.frame
s 上运行,而且在list
s 上运行;它不关心列表的每个元素是否有不同的长度。
foo = list(
letters = c("a", "b", "c"),
numbers = c(1, 2),
booleans = c(T)
)
expand.grid(foo)
letters numbers booleans
1 a 1 TRUE
2 b 1 TRUE
3 c 1 TRUE
4 a 2 TRUE
5 b 2 TRUE
6 c 2 TRUE
因此,要生成 adata.frame
的组合,NA
省略 s:
df_combos <- expand.grid(lapply(df_NAs, na.omit))
df_combos
X1 X2 X3
1 a k e
2 b k e
3 a l e
4 b l e
5 a m e
6 b m e
7 a k t
8 b k t
9 a l t
10 b l t
11 a m t
12 b m t
13 a k l
14 b k l
15 a l l
16 b l l
17 a m l
18 b m l
19 a k p
20 b k p
21 a l p
22 b l p
23 a m p
24 b m p
现在我们需要从combos
. 要从值向量创建单个字符串,您可以使用:
paste(c("a", "b", "c"), collapse = "")
[1] "abc"
因此,要从 的每一行创建一个字符向量df_combos
,您可以使用 将 的每一行发送data.frame
到paste
函数apply
:
apply(combos, 1, paste, collapse = "")
[1] "ake" "bke" "ale" "ble" "ame" "bme" "akt" "bkt" "alt" "blt" "amt" "bmt" "akl" "bkl" "all" "bll" "aml" "bml" "akp"
[20] "bkp" "alp" "blp" "amp" "bmp"
要在字母之间放置空格,请将collapse
参数更改为" "
,如下所示:
apply(combos, 1, paste, collapse = " ")
[1] "a k e" "b k e" "a l e" "b l e" "a m e" "b m e" "a k t" "b k t" "a l t" "b l t" "a m t" "b m t" "a k l" "b k l"
[15] "a l l" "b l l" "a m l" "b m l" "a k p" "b k p" "a l p" "b l p" "a m p" "b m p"
如果你真的想在一行完全不可读的代码中完成这一切,这里是:
apply(expand.grid(lapply(df_NAs, na.omit)), 1, paste, collapse = "")
推荐阅读
- javascript - 有没有办法在 React 中留下注释/注释 PDF 文件?
- python - QMessageBox 在计算时阻止父级
- javascript - Flexbox 生成器在我的反应应用程序中显示不好
- java - Akka Stream 中的物化值是如何工作的
- typeclass - 在精益类定义中扩展或推断(PID / UFD)
- python - 有没有办法让海龟运动更顺畅
- r - 你如何比较 R 中的两个字符串?
- python - 使用 Python Openpyxl 和 For 循环连接 Excel 中的两个单元格
- python-3.x - 如何在 python 中将数据编码为 der?
- angular6 - 错误:没有名称的表单控件的值访问器:“答案”