Более быстрый способ изменения нескольких переменных - PullRequest
1 голос
/ 12 мая 2019

Я новичок в R и Stack, поэтому, пожалуйста, дайте мне знать, какой этикет я невольно игнорирую.

У меня есть несколько переменных, которые мне нужно перекодировать. Они последовательны. Я использовал это и экспериментировал с mutate (включая 2:20, чтобы получить эти последовательные переменные), но не могу заставить его работать. амер мой дф

amer$ir1 <- recode(amer$ir01, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$ir02 <- recode(amer$ir02, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$ir03 <- recode(amer$ir03, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$t01 <- recode(amer$t01, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$t02 <- recode(amer$t02, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$t03 <- recode(amer$t03, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$t04 <- recode(amer$t04, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$m01 <- recode(amer$m01, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$m02 <- recode(amer$m02, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")
amer$m03 <- recode(amer$m03, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA")

Ответы [ 3 ]

2 голосов
/ 12 мая 2019

Это должно помочь,

amer <- data.frame(ir01 = 1:20, ir02 = 1:20, ir03 = 1:20)

library(memisc) # This is where recode is from
apply(amer, 2, function(x) recode(x, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA"))

В @Rui Barradas, чтобы сохранить класс dataframe, используйте следующее при запуске функции apply,

amer[] <- apply(amer, 2, function(x) recode(x, "1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA"))

Предполагается, что ваши данные выглядят примерно так:

> amer
   ir01 ir02 ir03 ...
1     1    1    1 ...
2     2    2    2 ...
3     3    3    3 ...
4     4    4    4 ...
5     5    5    5 ...
6     6    6    6 ...
7     7    7    7 ...
8     8    8    8 ...
9     9    9    9 ...
10   10   10   10 ...
11   11   11   11 ...
12   12   12   12 ...
13   13   13   13 ...
14   14   14   14 ...
15   15   15   15 ...
16   16   16   16 ...
17   17   17   17 ...
18   18   18   18 ...
19   19   19   19 ...
20   20   20   20 ...

Это возвращает,

      ir01 ir02 ir03
 [1,]    4    4    4
 [2,]    3    3    3
 [3,]    2    2    2
 [4,]    1    1    1
 [5,]    5    5    5
 [6,]    6    6    6
 [7,]    7    7    7
 [8,]   NA   NA   NA
 [9,]   NA   NA   NA
[10,]   10   10   10
[11,]   11   11   11
[12,]   12   12   12
[13,]   13   13   13
[14,]   14   14   14
[15,]   15   15   15
[16,]   16   16   16
[17,]   17   17   17
[18,]   18   18   18
[19,]   19   19   19
[20,]   20   20   20
1 голос
/ 12 мая 2019

Вы также можете рассмотреть data.table решение этой проблемы.Он хорошо масштабируется для больших наборов данных, где может быть более 100 000 строк.Я использую recode из пакета car, потому что он хорошо работает с data.table.Я получаю ошибку, используя memisc с синтаксисом recode_key ниже.В любом случае, вот что вы можете сделать, чтобы сложить все вместе:

library(data.table)
library(car)
amer <- data.table(ir01 = 1:20, ir02 = 1:20, ir03 = 1:20) #read data in as a data.table

recode_key<-c("1 = 4; 2 = 3; 3 = 2; 4 = 1; 8 = NA; 9 = NA") #modify this to add other recodes
recode_cols<-c("ir01","ir02") #If you want to only make changes to specific columns list them here

amer[,eval(recode_cols):=lapply(.SD,function(x) recode(x,recode_key)),.SDcols=recode_cols] #This will change the columns in the data.table

Обратите внимание, что я использовал eval, чтобы убедиться, что он не создал новый столбец с именем recode_cols!Затем вы используете специальный символ .SD, поэтому функция recode выполняет итерации по столбцам data.table.Если вы хотите применить перекодировку ко всем столбцам, вы можете просто оставить аргумент .SDcols пустым и, конечно, удалить eval(recode_cols): и просто начать с lapply.

Последнее, что следует отметить, - мне не нужно было присваивать последнюю строку кода глобальной переменной.Причина data.table в том, что он автоматически обновляет исходные данные с помощью указателей, поэтому копирование не требуется.Тем не менее, будьте осторожны, потому что если вы дважды запустите последнюю строку кода, вы вернетесь к тому, с чего начали, кроме NAs.Дайте мне знать, если это объяснение имеет смысл.

1 голос
/ 12 мая 2019

Вы можете определить в векторе recode, какие переменные нужно изменить, и lapply над ним с помощью ifelse, в котором вы выполняете некоторую арифметику.

Предположим, этот кадр данных

head(df1)
#   ir01 ir02 dont.change.me
# 1    1    4              1
# 2    8    8              2
# 3    1    8              3
# 4    1    8              4
# 5    2    4              5
# 6    4    2              6

Определить recode вектор,

recode <- c("ir01", "ir02")

и lapply для определенных столбцов внутри:

df1[recode] <- lapply(df1[recode], function(x) ifelse(x %in% 8:9, NA, abs(x - 5)))
head(df1)
#   ir01 ir02 dont.change.me
# 1    4    1              1
# 2   NA   NA              2
# 3    4   NA              3
# 4    4   NA              4
# 5    3    1              5
# 6    1    3              6

Взгляды перевернуты, только те, которые должны!

Факторы?

Иногда эти парни factors,

df1$ir01 <- lapply(df1$ir01, as.factor)  # intentionally change `ir01` into factor
str(df1)
# 'data.frame': 20 obs. of  3 variables:
#  $ ir01          : Factor w/ 6 levels "1","2","3","4",..: 1 5 1 1 2 4 2 2 1 4 ...
#  $ ir02          : int  4 8 8 8 4 2 4 3 2 1 ...
#  $ dont.change.me: int  1 2 3 4 5 6 7 8 9 10 ...

, и мы могли бы расширить нашу функцию, чтобы сделать их:

df1[recode] <- lapply(df1[recode], 
                      function(x) {
                        if (is.factor(x))
                          x <- as.numeric(levels(x))[x]
                        ifelse(x %in% 8:9, NA, abs(x - 5))
                      })
head(df1)
#   ir01 ir02 dont.change.me
# 1    4    1              1
# 2   NA   NA              2
# 3    4   NA              3
# 4    4   NA              4
# 5    3    1              5
# 6    1    3              6

Данные

df1 <- structure(list(ir01 = c(1L, 8L, 1L, 1L, 2L, 4L, 2L, 2L, 1L, 4L, 
                               1L, 8L, 9L, 4L, 2L, 2L, 3L, 1L, 1L, 3L), 
                      ir02 = c(4L, 8L, 8L, 8L, 4L, 2L, 4L, 3L, 2L, 1L, 
                               2L, 9L, 3L, 9L, 2L, 4L, 4L, 9L, 2L, 8L), 
                      dont.change.me = 1:20), class = "data.frame", 
                 row.names = c(NA, -20L))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...