我是一个初学者,想知道如何不剪切和粘贴60行代码。这是我的数据帧
df <- data.frame(
stringsAsFactors = FALSE,
id = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L),
people = c("marge","homer","homer",
"homer","marge","bart","homer","homer","marge")
)
我试着写一个函数,这样我就可以指定输入,使这更容易。实际上,我希望x是一个向量,但我甚至无法将其用于单个观测。
lisaList <- function (x) {
df[df$id==x, "people"] <- "lisa"
}
#vector with the list of id's I want to change to "lisa"
myList=c(1,2,3)
我尝试过的不起作用的东西
lisaList(myList)
这不起作用
lisaL <- function (x) {
if(df$id==x) df[df$id==x, "people"] <- "lisa" }
lisaL(myList)
我也试着用mutate写一些东西,然后用purrr,但我也不明白。
我希望在";id";其=1、2或3被改变为"0";lisa";所以我最终得到了这个
df <- data.frame(
stringsAsFactors = FALSE,
id = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L),
people = c("lisa","lisa","lisa",
"homer","marge","bart","homer","homer","marge")
)
谢谢。
跟进我的原始问题
谢谢你们两个!这些答案帮助我跨过了一道障碍。现在,我还有另外两个问题,通过在我的df中添加另一列来扩展这个函数。后续问题1现在我希望能够输入需要更改的观察结果。
df <- data.frame(
stringsAsFactors = FALSE,
id = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L),
people = c("bart","lisa","lisa",
"homer","marge","bart","homer","homer","marge"),
pets = c("dog","wolf","horse",
"bat","mouse","mole","gopher","bat","bat")
)
# new function
list3 <- function(dat, x, y) {
dat %>%
mutate(people = replace(people, id %in% x, y))
}
myList=c(3,4,5)
list3 (df, myList, 'cat')
这可以正常工作,但我的功能中是否有可以更改的内容,这样用户就不需要用"输入观察结果了?
我能够实现一些接近我想要的东西,但这需要创建一个新的列表。
otherList <- c("ground hog")
list3 (df, myList, otherList)
后续问题2现在我希望用户能够输入要更改的列,而不是在函数中硬编码列名。我一直在试图弄清楚这一点(这就是为什么我认为我可能会尝试在函数中使用mutate的替代方法(,但现在我觉得我已经很接近了,我想看看如何做到这一点。
所以第一次尝试没有成功。
list4 <- function(dat, x, y, z) {
dat %>%
mutate(z = replace(z, id %in% x, y))
}
mycol <- c('pets')
list4(df, myList, 'birds', mycol)
但这并没有奏效。
list4 <- function(dat, x, y, z) {
dat %>%
mutate((enquo(z)) = replace( (!!z), id %in% x, y))
}
mycol <- c('pets')
list4(df, myList, 'birds', mycol)
以及许多其他版本尝试使用{{}}或指定enquo((和!!
你能帮我弄清楚如何输入列名吗?再次感谢你们两位的初步帮助!
我建议在dplyr
管道中使用ifelse
:
lisaList <- function (x) {
df%>%
mutate(people=ifelse(id %in% x,"lisa", people))
}
myList=c(1,2,3)
lisaList(myList)
id people
1 1 lisa
2 2 lisa
3 3 lisa
4 4 homer
5 5 marge
6 6 bart
7 7 homer
8 8 homer
9 9 marge
关于第三个问题,可以使用across
在mutate
中指定变量名。为了提高可读性,我已经将参数重命名为您的函数:
list3 <- function(dat, rowindex, replacestring, colnamevar) {
dat %>%
mutate(across(colnamevar, ~ifelse(id %in% rowindex, replacestring, .)))
}
list3(df, myList, 'birds', mycol)
id people pets
1 1 bart dog
2 2 lisa wolf
3 3 lisa birds
4 4 homer birds
5 5 marge birds
6 6 bart mole
最后,不知道有什么方法可以让R将未引用的文本识别为字符串而不是变量。
我们可以使用%in%
而不是==
df$people[df$id %in% 1:3] <- "lisa"
因此,功能将是
lisaL <- function (dat, x) {
dat$people[dat$id %in% x] <- "lisa"
dat
}
lisaL(df, myList)
# id people
#1 1 lisa
#2 2 lisa
#3 3 lisa
#4 4 homer
#5 5 marge
#6 6 bart
#7 7 homer
#8 8 homer
#9 9 marge
或使用replace
和mutate
library(dplyr)
lisaList2 <- function(dat, x) {
dat %>%
mutate(people = replace(people, id %in% x, 'lisa'))
}
如果我们想使用==
,那么一个选项是用lapply
或for
循环"myList",创建一个逻辑向量,用|
将其Reduce
转换为单个逻辑向量,并分配
listList3 <- function(dat, x) {
dat$people[Reduce(`|`, lapply(x, function(u) dat$id == u))] <- 'lisa'
dat
}
listList3(df, myList)