#r
Вопрос:
У меня есть фрейм данных, подобный этому:
start = 0
end = 2
v1<-round ( runif ( n=20, min=start, max=end ))
v2<-round ( runif ( n=20, min=start, max=end ))
v3<-round ( runif ( n=20, min=start, max=end ))
df <- data.frame(v1,v2,v3)
Я хочу, чтобы 20 процентов каждого числа в каждом столбце было изменено на 5. Например, если у меня есть 10 чисел «1» в первом столбце, я хочу, чтобы 20 процентов этого числа «1» было преобразовано в «5».
Как я могу решить эту проблему в программе R?
Спасибо, что ответили!
Комментарии:
1. Просто случайным образом заменить заданный процент на какое-то число? Кроме того, как вы считаете «десять чисел в первой колонке»?
Ответ №1:
Я создал простую функцию, которую вы можете использовать внутри apply
(или purrr::map
или purrr::map_df
функции)
# reproducibility
set.seed(4242)
start = 0
end = 2
v1 <-round(runif(n = 20, min = start, max = end))
v2 <-round(runif(n = 20, min = start, max = end))
v3 <-round(runif(n = 20, min = start, max = end))
df1 <- data.frame(v1,v2,v3)
# replace the value with 5 for the chosen number in the vectors
change_number <- function(x, number) {
x <- replace(x, sample(which(x == number),
length(which(x == number)) * 0.2,
replace = FALSE), 5)
x
}
# reproducibility
set.seed(42)
df2 <- apply(df1, 2, change_number, number = 1)
# if you need it returned as a data.frame instead of a matrix run the following line
# df2 <- data.frame(df2)
df2
v1 v2 v3
[1,] 2 0 1
[2,] 5 5 0
[3,] 0 0 0
[4,] 1 1 1
[5,] 1 1 1
[6,] 2 1 1
[7,] 2 2 1
[8,] 0 5 1
[9,] 1 1 1
[10,] 2 1 0
[11,] 0 1 2
[12,] 1 0 2
[13,] 0 2 0
[14,] 2 1 1
[15,] 2 0 2
[16,] 2 0 5
[17,] 0 2 0
[18,] 1 1 5
[19,] 1 1 2
[20,] 0 1 1
Ответ №2:
Это звучит так, как будто вы хотите, чтобы 20% каждого числа в каждом столбце было заменено на 5. В этом случае попробуйте воспользоваться этой функцией replaceNumbers
. Аргумент repl=
определяет замену в вашем случае 5
. Если вы установите at_least_one=
TRUE
это значение , по крайней мере одно из тех чисел, где 20% их встречаемости меньше единицы, также будет заменено.
replaceNumbers <- function(x, repl, at_least_one=FALSE) {
sapply(unique(x), function(z) {
w <- which(x == z)
l <- length(w)
if (l < 3 amp; at_least_one) s <- 1
else s <- l*.2
x[sample(w, s)] <<- repl
})
return(x)
}
set.seed(42) ## for sake of reproducibility
res <- as.data.frame(lapply(df, replaceNumbers, repl=5, at_least_one=FALSE))
Сравнение результатов с оригиналом:
data.frame(df, res)
# v1 v2 v3 v1.1 v2.1 v3.1
# 1 2 2 1 5 5 1
# 2 2 0 1 2 0 5
# 3 1 2 0 5 2 0
# 4 2 2 2 2 2 5
# 5 1 0 1 1 5 1
# 6 1 1 2 1 1 2
# 7 1 1 2 1 1 2
# 8 0 2 1 0 2 1
# 9 1 1 2 5 1 2
# 10 1 2 1 1 2 1
# 11 1 1 1 1 5 1
# 12 1 2 1 1 2 1
# 13 2 1 1 2 1 1
# 14 1 1 2 1 1 2
# 15 1 0 0 1 0 0
# 16 2 2 1 2 2 1
# 17 2 0 1 2 0 5
# 18 0 0 0 0 0 0
# 19 1 2 1 1 2 1
# 20 1 1 1 1 1 1
Данные:
df <- structure(list(v1 = c(2, 2, 1, 2, 1, 1, 1, 0, 1, 1, 1, 1, 2,
1, 1, 2, 2, 0, 1, 1), v2 = c(2, 0, 2, 2, 0, 1, 1, 2, 1, 2, 1,
2, 1, 1, 0, 2, 0, 0, 2, 1), v3 = c(1, 1, 0, 2, 1, 2, 2, 1, 2,
1, 1, 1, 1, 2, 0, 1, 1, 0, 1, 1)), class = "data.frame", row.names = c(NA,
-20L))
Ответ №3:
Итак, вы хотите, чтобы 20% «1» в кадре данных стали 5, правильно?
Сначала давайте спросим позиции каждого числа 1, используя which()
. Затем возьмите 20% от then и, наконец, присвоите этим позициям значение «5».
df1s = which(df==1)
df1s = sample(df1s,length(df1s)*0.2,replace=F)
df[df1s] = 5