我在我的数据上使用了dplyr
来创建这样的数据子集:
dd <- data.frame(ID = c(700689L, 712607L, 712946L, 735907L, 735908L, 735910L, 735911L, 735912L, 735913L, 746929L, 747540L),
`1` = c("eg", NA, NA, "eg", "eg", NA, NA, NA, NA, "eg", NA),
`2` = c(NA, NA, NA, "sk", "lk", NA, NA, NA, NA, "eg", NA),
`3` = c(NA, NA, NA, "sk", "lk", NA, NA, NA, NA, NA, NA),
`4` = c(NA, NA, NA, "lk", "lk", NA, NA, NA, NA, NA, NA),
`5` = c(NA, NA, NA, "lk", "lk", NA, NA, NA, NA, NA, NA),
`6` = c(NA, NA, NA, "lk", "lk", NA, NA, NA, NA, NA, NA))
我现在想检查除ID以外的每一列,如果它包含某些字符串。在这个例子中,我想为每个ID创建一个带有“1”的列,其中包含一个带有“eg”和“0”的列。同样,还有一列告诉我其他列中是否有“sk”或“lk”。之后,可以从data.frame
中删除除ID以外的旧列对我而言,困难的部分是使用动态数量的列,因为我的dplyr
- 子集将根据具体情况返回不同数量的列,但我需要检查每个列中创建的列每个案例。我想首先使用unite将所有字符串放在一起,但我会遇到同样的问题:如何将除第一个ID之外的所有列联合起来。
如果这可以在dplyr
内解决,那将是完美的,但任何有效的解决方案都会受到赞赏。
结果应如下所示:
result <- data.frame(ID = c(700689L, 712607L, 712946L, 735907L, 735908L, 735910L, 735911L, 735912L, 735913L, 746929L, 747540L),
with_eg = c(1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0),
with_sk_or_lk = c(0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0))
答案 0 :(得分:1)
根据您的描述,您希望一列检查&#34;例如&#34;和另一列检查&#34; lk&#34;和&#34; sk&#34;。如果是这种情况,那么以下基本R方法将起作用。
dfNew <- cbind(id=dd[1],
eg=pmin(rowSums(dd[-1] == "eg", na.rm=TRUE), 1),
other=pmin(rowSums(dd[-1] == "sk" | dd[-1] == "lk", na.rm=TRUE), 1))
这里存在&#34;例如&#34;检查整个data.frame(id列除外)并返回逻辑矩阵,rowSums
在行中添加TRUE值,na.rm
删除NA,然后pmin
取rowSums
和1的最小输出,以便将2的所有元素替换为1,并保留任何0的值。
同样的逻辑适用于&#34;其他&#34;变量,除了存在&#34; lk&#34;或&#34; sk&#34;在初始逻辑矩阵中检查。最后,data.frame
返回一个包含所需值的3列data.frame。
返回
dfNew
ID eg other
1 700689 1 0
2 712607 0 0
3 712946 0 0
4 735907 1 1
5 735908 1 1
6 735910 0 0
7 735911 0 0
8 735912 0 0
9 735913 0 0
10 746929 1 0
11 747540 0 0
答案 1 :(得分:0)
这是一个公认的hapy dplyr / purrr解决方案。鉴于您的ID似乎并不相同,例如&#39;,&#39; sk&#39;或者&#39; lk&#39;,我没有&#39; ; t包含任何不搜索ID列的内容。
library(dplyr)
library(purrr)
dd %>%
split(.$ID) %>%
map_df(~ data_frame(
ID = .x$ID,
eg = ifelse(any(.x == 'eg', na.rm = TRUE), 1, 0),
other = ifelse(any(.x == 'lk' | .x == 'sk', na.rm = TRUE), 1, 0)
))