我是一个初学者,想弄清楚如何不剪切和粘贴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的每个观测值都更改为“ 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添加另一列,我还有另外2个关于此功能的问题。 关注问题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()和!!
您能帮我弄清楚如何输入列名吗?再次感谢你们俩的初步帮助!
答案 0 :(得分:1)
我建议在ifelse
管道中使用dplyr
:
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将未引用的文本识别为字符串而不是变量的方法。
答案 1 :(得分:0)
我们可以使用%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)