我正试图在R中做一个有点复杂的任务。
我有data frame
(为简单起见)三列。
第1列是一个字符串 第2列是整数 第3列是整数。
我想获取包含第1列中某个子字符串并且第2列具有精确值的所有观察结果,并将第3列替换为数字1。
也就是说,我有以下dataframe
:
x <- data.frame(x1 = c("bob","jane","bob","bobby","bob","jane","bobby","bob","jane","bob"),
x2 = c(1,1,1,1,1,2,2,2,2,2),
x3 = c(13,22,3,34,10,23,53,42,13,35))
并且,我想选择第1列包含bob和第2列== 1的观察结果,并将第3列更改为1,这样我最终得到:
y1 <- c("bob","jane","bob","bobby","bob","jane","bobby","bob","jane","bob")
y2 <- c(1,1,1,1,1,2,2,2,2,2)
y3 <- c(1,22,1,1,1,23,53,42,13,35)
y <- data.frame(y1,y2,y3)
我想在一个真正非常大的数据集中做到这一点。拆分数据集并将其重新组合在一起是不可行的。
我尝试过使用grep
,但是当我尝试同时进行两场比赛时,它都无法正常工作。此外,我尝试了子集,但后来我必须拆分dataframe
并将其重新组合在一起。
非常感谢提前。
答案 0 :(得分:5)
使用R meteor shell
函数进行逻辑索引的能力,这真的很容易:
[<-
要阅读代码,您应将其视为:&#34; > x$x3[ grepl("bob", x$x1) & x$x2 == 1] <- 1
> x
x1 x2 x3
1 bob 1 1
2 jane 1 22
3 bob 1 1
4 bobby 1 1
5 bob 1 1
6 jane 2 23
7 bobby 2 53
8 bob 2 42
9 jane 2 13
10 bob 2 35
的每一行,其中列&#39; x1&#39;有&#34; bob&#39;和列&#39; x2&#39;等于1,...您将值1分配给列&#39; x3&#39;。&#34;如果您想要一个具有该值的新对象,您可以使用x
制作x的副本,然后再进行处理。
答案 1 :(得分:1)
x1 <- c("bob","jane","bob","bobby","bob","jane","bobby","bob","jane","bob")
x2 <- c(1,1,1,1,1,2,2,2,2,2)
x3 <- c(13,22,3,34,10,23,53,42,13,35)
x <- data.frame(x1,x2,x3)
rows <- grepl("bob", x[,1]) & x[,2] == 1 # Logical Selector Of Rows
x[rows, 3] <- 1
除了表示法之外,我的答案和@ 42-答案之间的主要区别是我的逻辑选择符行短语仅在数据帧上运行,而@ 42-引用其中一个原始向量(可能是监督)。
x1 x2 x3
1 bob 1 1
2 jane 1 22
3 bob 1 1
4 bobby 1 1
5 bob 1 1
6 jane 2 23
7 bobby 2 53
8 bob 2 42
9 jane 2 13
10 bob 2 35
答案 2 :(得分:1)
用户 akrun 使用dplyr
包来解决类似的问题here以及用户 docendo discimus 的更快变体here。在您的情况下,代码将是:
x %>% mutate(x3 = replace(x3, x1 == 'bob' & x2 == 1, 1))
或
x %>% mutate(x3 = replace(x3, which(x1 == 'bob' & x2 == 1), 1))
如果您想直接更新x,可以与%<>%
包中的magrittr
运算符结合使用:
x %<>% mutate(x3 = replace(x3, x1 == 'bob' & x2 == 1, 1))
答案 3 :(得分:1)
您还可以使用data.table
包来获得高性能:
library(data.table)
setDT(x)[grepl('bob', x1) & x2==1, x3:=1][]
# x1 x2 x3
# 1: bob 1 1
# 2: jane 1 22
# 3: bob 1 1
# 4: bobby 1 1
# 5: bob 1 1
# 6: jane 2 23
# 7: bobby 2 53
# 8: bob 2 42
# 9: jane 2 13
#10: bob 2 35
答案 4 :(得分:0)
如果你正在寻找子字符串grep
,那么在这种情况下可以使用' ifelse '函数。使用x作为数据框并希望更改 x $ x3 ,执行以下操作,
1:查找具有所需子字符串的那些
req_sub<-grep("bob",x$x1)
这将返回x3中子字符串
中匹配的所有位置2:在第x3列进行更改
x$x3[grep("bob",x$x1)]<-ifelse(x[req_sub,]$x2==1,1,x[req_sub,]$x3)
以下是输出
x1 x2 x3
1 bob 1 1
2 jane 1 22
3 bob 1 1
4 bobby 1 1
5 bob 1 1
6 jane 2 23
7 bobby 2 53
8 bob 2 42
9 jane 2 13
10 bob 2 35