Функция apply возвращает список списков, если выполняется дважды - PullRequest
0 голосов
/ 12 октября 2018

У меня есть df, подобный этому

a1 <- c(1,2,NA)
a2 <- c(3,4,NA)
a3 <- c(4,5,6)
a1_fill <- c(1,2,3)
a2_fill <- c(3,4,5)
a3_fill <- c(4,5,6)
b1 <- c(4,3,1)
b2 <- c(2,NA,9)
b3 <- c(NA,3,5)
b1_fill <- c(4,3,1)
b2_fill <- c(2,1,9)
b3_fill <- c(8,3,5)
df <- data.frame(a1,a2,a3,b1,b2,b3,a1_fill,a2_fill,a3_fill,b1_fill,b2_fill,b3_fill)

Я хочу создать два новых столбца со значениями из столбцов fill, которые не отображаются в соответствующих столбцах a или b.Я делаю так:

df$missingA <- apply(df,1,function(x) setdiff(x[which(grepl("a",names(x),fixed = TRUE) & grepl("fill",names(x),fixed = TRUE))],x[which(grepl("a",names(x),fixed = TRUE) & !grepl("fill",names(x),fixed = TRUE))]))
df$missingB <- apply(df,1,function(x) setdiff(x[which(grepl("b",names(x),fixed = TRUE) & grepl("fill",names(x),fixed = TRUE))],x[which(grepl("b",names(x),fixed = TRUE) & !grepl("fill",names(x),fixed = TRUE))]))

. По какой-то причине, когда я запускаю приведенный выше код, строка, которая запускается второй, возвращает список списков, тогда как первая возвращает список числовых.Почему это?

1 Ответ

0 голосов
/ 12 октября 2018

Это зависит от порядка, в котором выполняются строки.Мы можем использовать приведенный ниже код для определения класса элементов в столбцах

class(df$missingA[[1]]) # Class of first element is numeric
class(df$missingB[[1]]) # Class of first element is list

Начиная с чистого набора данных, если вы сначала создадите отсутствующий B, а затем создаете отсутствующий A, вы увидите, что отсутствующий A будетсписок списков, тогда как missingB будет списком чисел (типы поменялись местами).

df$missingB <- apply(df,1,function(x) 
  setdiff(
    x[which(
      grepl("b",names(x),fixed = TRUE) & 
      grepl("fill",names(x),fixed = TRUE))
    ],
    x[which(
      grepl("b",names(x),fixed = TRUE) & 
      !grepl("fill",names(x),fixed = TRUE))
    ]
  )
)


df$missingA <- apply(df,1,function(x) 
  setdiff(
    x[which(
      grepl("a",names(x),fixed = TRUE) & 
      grepl("fill",names(x),fixed = TRUE))
    ],
    x[which(
      grepl("a",names(x),fixed = TRUE) & 
      !grepl("fill",names(x),fixed = TRUE))
    ]
  )
)

class(df$missingA[[1]]) # Class of first element is list
class(df$missingB[[1]]) # Class of first element is numeric

Я предполагаю, что происходит следующее.Вы начинаете с кадра данных, содержащего только числовые столбцы.R пытается помочь, сопоставляя тип вашего списка с числовым.Когда второй столбец добавляется, информационный фрейм больше не состоит только из числовых столбцов, поскольку один из типов теперь является списком, и поэтому R не пытается обновить тип.

Чтобы проверить это, вы можете добавитьнет числового столбца перед добавлением отсутствующих A и отсутствующих B, например:

df$text <- list("a","b","C")

Теперь пропущенные и отсутствующие B будут созданы как список списка

Еще один способ сохранить типы в том виде, как они создаютсяоператоры apply - это присвоение выходных данных промежуточной переменной

missingA <- apply(df,1,function(x) 
setdiff(
  x[which(
    grepl("a",names(x),fixed = TRUE) & 
    grepl("fill",names(x),fixed = TRUE))
  ],
  x[which(
    grepl("a",names(x),fixed = TRUE) & 
    !grepl("fill",names(x),fixed = TRUE))
  ]
 )
)

df$missingA <- missingA

Подводя итог, можно заметить, что разница не в вызванных операторах применения или выходных данных, а в том, как данные добавляются вкадр данных.Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...